我正在尝试在任意类型的列表上创建一个函数,并进行一些计算,将中间结果存储在一个 STArray 中。基本上,我想做这样的事情(是的,这是一个愚蠢的例子):
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 s...”),我仍然会得到一个不同的错误:
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 }'
如果我改为将出现的三个“a”更改为 Char,那么我当然可以编译它。但我想要一个可用于 [Int]、[Char]、[Int->Int] 或其他的通用函数。
我该怎么做?谢谢!