I'm trying to make a function on a list of arbitrary type, and do some computation, storing the intermediate results in an STArray. Basically, I want to do something like this (yes, this is a silly example):
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
However, ghci (version 7.4.2) gives this spectacular error:
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 }'
If I remove the type signature (":: ST s..."), I still get a different error:
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 }'
If I instead change three occurrences of "a" to, say, Char, then of course I can compile it. But I want a generic function that can be used for [Int], [Char], [Int->Int], or whatever.
How can I do it? Thanks!