ugliness with state parameter in ST stuff
Hal Daume III
hdaume@ISI.EDU
Tue, 6 Aug 2002 11:19:37 -0700 (PDT)
Sorry for the flood of emails this morning, but I've got something which
has really got me scratching my head.
Suppose I have a class:
> class Foo a where
> foo :: a -> IO Int
and a datatype with a single function:
> data Bar s = Bar (STArray s Int Int)
>
> getFirst :: Bar s -> ST s Int
> getFirst (Bar arr) = readArray arr 0
Now, I want to make (Bar s) and instance of Foo. But I can't seem to do
this. If I use:
> instance Foo (Bar s) where
> foo = stToIO . getFirst
GHC complains:
Cannot unify the type-signature variable `s'
with the type `RealWorld'
Expected type: Bar s -> IO Int
Inferred type: Bar RealWorld -> IO Int
In the expression: stToIO . getFirst
In the definition of `foo': stToIO . getFirst
and if I use:
> instance Foo (Bar s) where
> foo = return . runST . getFirst
GHC complains:
Inferred type is less polymorphic than expected
Quantified type variable `s' escapes
Expected type: ST s a -> c
Inferred type: (forall s1. ST s1 a) -> a
In the first argument of `(.)', namely `runST'
In the second argument of `(.)', namely `runST . getFirst'
Is there no way to do this? I can change the definition of Foo to:
> class Foo2 a where
> foo2 :: (forall s . a s) -> IO Int
I can define:
> instance Foo2 Bar where
> foo2 = stToIO . getFirst
Which I suppose works, but the problem is that in real life, "Foo" is
"Binary" and I can't really change it.
Suggestions? (Other than simply moving all my ST stuff over to the IO
monad?)
- Hal
--
Hal Daume III
"Computer science is no more about computers | hdaume@isi.edu
than astronomy is about telescopes." -Dijkstra | www.isi.edu/~hdaume