Re: [Haskell] Help in understanding a type error involving forall and class constraints

On Wed, 2004-06-30 at 12:00, MR K P SCHUPKE wrote:
Ahh.. I see whats happening:
MArray (STUArray s) a (ST s) => String -> String -> ST s (UArray (Int,Int) a)
IArray UArray a => String -> String -> a
nothing here is specifying a... you cannot leave a polymorphic in this case.
You need to supply the constraint "MArray (STUArray s) a (ST s)" to distString but "s" is not in context...
Right, because the return type of distString Int is an instance of MArray. But if we try to make 'a' polymorphic then we can't specify the constraint because it involves 's'. So the obvious follow-on question, is is there any intermediate point where 's' is in scope where we can supply a type annotation to supply the context or is it simply impossible? To restate the question for Haskell-Cafe readers: Is it possible to return an arbitrary unboxed array that was constructed in the ST monad (as an STUArray)? The issue is that you end up with a MArray class constraint that involves the state thread's 's' parameter, but this type variable gets 'hidden' by runST which universally quantifies over it. runST :: forall a. (forall s. ST s a) -> a Duncan

On Wed, 2004-06-30 at 12:54, Duncan Coutts wrote:
To restate the question for Haskell-Cafe readers: Is it possible to return an arbitrary unboxed array that was constructed in the ST monad (as an STUArray)?
The issue is that you end up with a MArray class constraint that involves the state thread's 's' parameter, but this type variable gets 'hidden' by runST which universally quantifies over it. runST :: forall a. (forall s. ST s a) -> a
I'm inclined to believe it is impossible. The author of ghc's mutable array libraries (probably Simon M) notes in a comment in the code: -- I don't know how to write a single rule for listUArrayST, because -- the type looks like constrained over 's', which runST doesn't -- like. In fact all MArray (STUArray s) instances are polymorphic -- wrt. 's', but runST can't know that. For that reason the modules contains rewrite rules for each unboxable type rather than a single polymorphic rule: {-# RULES "listArray/UArray/Bool" listArray = \lu (es :: [Bool]) -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray) "listArray/UArray/Char" listArray = \lu (es :: [Char]) -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray) "listArray/UArray/Int" listArray = \lu (es :: [Int]) -> runST (listUArrayST lu es >>= unsafeFreezeSTUArray) etc... Duncan
participants (1)
-
Duncan Coutts