Tôi muốn thực hiện một thuật toán lập trình động đa hình trong loại điểm số; đây là phiên bản 1D được đơn giản hóa không có điều kiện biên:Xem lại STUArrays đa hình với các loại ràng buộc
{-# LANGUAGE ConstraintKinds, FlexibleContexts, RankNTypes, ScopedTypeVariables #-}
import Control.Monad
import Control.Monad.ST.Strict
import Data.Array.ST
import Data.Array.Unboxed
dynamicProgrammingSTU
:: forall e i . (
IArray UArray e,
forall s. MArray (STUArray s) e (ST s),
Ix i
)
=> (forall m . Monad m => (i -> m e) -> (i -> m e))
-> (i, i)
-> (i -> e)
dynamicProgrammingSTU prog bnds = (arr !) where
arr :: UArray i e
arr = runSTUArray resultArrayST
resultArrayST :: forall s . ST s (STUArray s i e)
resultArrayST = do
marr <- newArray_ bnds
forM_ (range bnds) $ \i -> do
result <- prog (readArray marr) i
writeArray marr i result
return marr
Ràng buộc không hoạt động;
Could not deduce (MArray (STUArray s) e (ST s))
arising from a use of `newArray_'
from the context (IArray UArray e,
forall s. MArray (STUArray s) e (ST s),
Ix i)
bound by the type signature for
dynamicProgrammingSTU :: (IArray UArray e,
forall s. MArray (STUArray s) e (ST s
), Ix i) =>
(forall (m :: * -> *). Monad m => (i -
> m e) -> i -> m e)
-> (i, i) -> i -> e
at example2.hs:(17,1)-(27,15)
Possible fix:
add (MArray (STUArray s) e (ST s)) to the context of
the type signature for resultArrayST :: ST s (STUArray s i e)
or the type signature for
dynamicProgrammingSTU :: (IArray UArray e,
forall s. MArray (STUArray s) e (ST s), I
x i) =>
(forall (m :: * -> *). Monad m => (i -> m
e) -> i -> m e)
-> (i, i) -> i -> e
or add an instance declaration for (MArray (STUArray s) e (ST s))
In a stmt of a 'do' block: marr <- newArray_ bnds
In the expression:
do { marr <- newArray_ bnds;
forM_ (range bnds) $ \ i -> do { ... };
return marr }
In an equation for `resultArrayST':
resultArrayST
= do { marr <- newArray_ bnds;
forM_ (range bnds) $ \ i -> ...;
return marr }
Failed, modules loaded: none.
Để tóm tắt, Could not deduce (MArray (STUArray s) e (ST s)) from the context forall s. MArray (STUArray s) e (ST s i)
. Lưu ý rằng việc thêm ràng buộc vào resultArrayST
chỉ cần đẩy vấn đề đến runSTUArray
.
Tôi hiện biết của bốn giải pháp sai lầm:
- Tránh các vấn đề với đóng hộp
STArray
s hoặc đơn giản là không monadicArray
s, có lẽ sử dụngseq
và tiếng nổ mô hình để giảm bớt những vấn đề bộ nhớ kết quả. - Phá vỡ hệ thống kiểu với
unsafeFreeze
vàunsafePerformIO
, mà ràng buộc đe dọaMArray IOUArray e IO
hoạt động tốt. - This giải pháp cho một vấn đề tương tự bằng cách sử dụng một kiểu chữ và chữ viết cho mỗi loại 'không thể mở hộp'.
- This một quy tắc viết lại GHC để chọn chức năng khác cho từng loại (và phiên bản
STArray
chung).
Tuy nhiên, tôi đặt câu hỏi này với hy vọng rằng tiện ích mở rộng ngôn ngữ hiện đại như ConstraintKinds
có thể cho phép tôi thể hiện ý định mã ban đầu của mình là forall s. MArray (STUArray s) e (ST s)
.
ghc-7.6.1 nói '' biến vị ngữ sai 'forall s. MArray (STUArray s) e (ST s) ''', mà đối với tôi có ý nghĩa hơn. –
Nếu chức năng 'prog' đơn thuần chỉ để thực hiện, tôi nghĩ p của bạn. 1 (tính toán thuần túy với các mẫu vụ nổ có thể xảy ra) sẽ là ít nhất của tệ nạn. – leventov