
Hi, I've spent some time running after a little bug in my code that seems to be caused by the following fact: If I want to use Data.Array.ST I can only use it with the strict ST monad. I would really like to use it with the lazy ST monad. Is there any way to do it? Further more, I got some really weird error messages. My file looked something like this: \begin{pseudocode} import Control.Monad.ST.Lazy import Data.Array.ST ... further down I have the following function.... foo :: Ix v => STArray s v Bool -> v -> ST s Bool foo a b = readArray a b \end{pseudocode} Now I got the following error message: formats/Graph.hs:91: Could not deduce (MArray (STArray s) Bool (ST s)) from the context (Ix v) Probable fix: Add (MArray (STArray s) Bool (ST s)) to the type signature(s) for `contains' Or add an instance declaration for (MArray (STArray s) Bool (ST s)) arising from use of `readArray' at formats/Graph.hs:91 In the definition of `foo': readArray a b The thing is, there is already an instance MArray (STArray s) e (ST s)! So what is the compiler complaining about? The problem is, it's not the right ST type! In the error message the name ST means two different things which is REALLY confusing and it took me a while to figure it out. One ST comes from Control.Monad.ST.Lazy and the other from Data.Array.ST. Is there any way to improve the situation? I'm not claiming these issues are bugs, but they certainly made my life a lot harder for a while. Cheers, /Josef

formats/Graph.hs:91: Could not deduce (MArray (STArray s) Bool (ST s)) from the context (Ix v) Probable fix: Add (MArray (STArray s) Bool (ST s)) to the type signature(s) for `contains' Or add an instance declaration for (MArray (STArray s) Bool (ST s)) arising from use of `readArray' at formats/Graph.hs:91 In the definition of `foo': readArray a b
The thing is, there is already an instance MArray (STArray s) e (ST s)! So what is the compiler complaining about? The problem is, it's not the right ST type! In the error message the name ST means two different things which is REALLY confusing and it took me a while to figure it out. One ST comes from Control.Monad.ST.Lazy and the other from Data.Array.ST.
In the compiler's defense, it's not ever mentioning the Strict.ST variant. It's simply saying that your function has a constraint: MArray (STArray s) Bool (ST s) for whichever ST is in scope. In your case it's Lazy.ST. It's the same (style) error message as when you say:
foo :: Show a => a -> a foo x = x + 2
which says: Could not deduce (Num a) from the context (Show a) Probable fix: Add (Num a) to the type signature(s) for `foo' arising from use of `+' at /nfs/isd/hdaume/Foo.hs:4 In the definition of `foo': x + 2 You've said "Show a", but you need to also say "Num a". As for the second question, you'd have to roll your own LazySTArray module. Probably the easiest way to do this would be to grab the source for STArray from CVS (you can even use the web interface) and then change it as necessary. Someone else can probabaly answer this better, but I don't think LazySTArrays are going to be very efficient. I can't, of course, back this up, but I think there's going to be either space or time leaks with this. Something you'll just have to try... - Hal
participants (2)
-
Hal Daume III
-
Josef Svenningsson