
On Sat, Oct 25, 2008 at 11:55 PM, Paul L
Tnaks for the clarification, please see my further questions below
On 10/25/08, Daniel Fischer
wrote: Sure, (g (flip readArray 0)) :: ST s Int, or, explicitly, forall s. ST s Int, there's nothing to restrict the s, so it's legitimate to pass it to runST.
..[snipped]..
What would be a generic mapST, which type should it have?
I tried this type for mapST, it doesn't work:
mapST :: (a -> ST s b) -> [a] -> [b] mapST f (x:xs) = runST (f x) : mapST f xs mapST f [] = []
By your reasoning, (f x) should have type forall s . ST s b, and should match what runST expects, but apparently GHC complains about it. Why?
From the perspective of code inside the definition of mapST, f is not
The problem is that the type variable s is determined by the caller of
mapST. If you write the type with explicit foralls, you get:
mapST :: forall a b s. (a -> ST s b) -> [a] -> [b]
polymorphic, because a, b, and s have already been determined.
The type you need is,
mapST :: forall a b. (forall s. a -> ST s b) -> [a] -> [b]
Now runST is able to pass an arbitrary type for s to f.
(GHC can silently convert between "forall s. a -> ST s b" and "a ->
forall s. ST s b".)
It may be helpful to rewrite the types with a more explicit notation.
For example,
runST :: (a :: *) -> ((s :: *) -> ST s a) -> a
mapST_wrong :: (a :: *) -> (b :: *) -> (s :: *) -> (f :: a -> ST s b)
-> [a] -> [b]
mapST_right :: (a :: *) -> (b :: *) -> (f :: (s :: *) -> a -> ST s b)
-> [a] -> [b]
--
Dave Menendez