我想在任意類型的列表上做一個函數,並做一些計算,將中間結果存儲在一個STArray中。基本上,我想要做這樣的事情(是的,這是一個愚蠢的例子):用ST數組寫一個多態的Haskell函數
import Control.Monad.ST
import Data.Array.ST
echoArray :: [a] -> [[a]]
echoArray input = runST $ do
let n = length input
buf <- newListArray (0, n-1) $ map (\x->[x]) input :: ST s (STArray s Int [a])
getElems buf
然而,ghci的(7.4.2版本)給出了這個壯觀的錯誤:
x.hs:7:12:
Couldn't match type `a' with `a1'
`a' is a rigid type variable bound by
the type signature for echoArray :: [a] -> [[a]] at x.hs:5:1
`a1' is a rigid type variable bound by
an expression type signature: ST s1 (STArray s1 Int [a1])
at x.hs:7:12
Expected type: ST s (STArray s Int [a1])
Actual type: ST s (STArray s Int [a])
In a stmt of a 'do' block:
buf <- newListArray (0, n - 1) $ map (\ x -> [x]) input ::
ST s (STArray s Int [a])
In the second argument of `($)', namely
`do { let n = length input;
buf <- newListArray (0, n - 1) $ map (\ x -> [...]) input ::
ST s (STArray s Int [a]);
getElems buf }'
如果我刪除類型簽名(「:: ST小號......」),我仍然得到一個不同的錯誤:
x.hs:7:12:
No instance for (MArray a0 [a] (ST s))
arising from a use of `newListArray'
Possible fix:
add an instance declaration for (MArray a0 [a] (ST s))
In the expression: newListArray (0, n - 1)
In a stmt of a 'do' block:
buf <- newListArray (0, n - 1) $ map (\ x -> [x]) input
In the second argument of `($)', namely
`do { let n = length input;
buf <- newListArray (0, n - 1) $ map (\ x -> [x]) input;
getElems buf }'
如果我反而變三級出現的「一」,比方說,char,那我當然會編譯它。但是我想要一個可用於[Int],[Char],[Int-> Int]或其他任何類型的泛型函數。
我該怎麼辦呢?謝謝!
也許您需要添加NoMonomorphismRestriction language pragma? –
@ИльяРезвов不,這不會在這裏幫助,不幸的是。 –