[Haskell-cafe] Can not use ST monad with polymorphic function

Dmitry Kulagin dmitry.kulagin at gmail.com
Thu Nov 29 13:50:59 CET 2012


Thank you, MigMit!

If I replace your type FoldSTVoid with:
data FoldMVoid = FoldMVoid {runFold :: Monad m => (Int -> m ()) -> m ()}

then everything works magically with any monad!
That is exactly what I wanted, though I still do not quite understand why
wrapping the type solves the problem

Dmitry


On Thu, Nov 29, 2012 at 12:01 AM, MigMit <miguelimo38 at yandex.ru> wrote:

> Yes, monomorphism. "do" binding requires your fold'' to be of some
> monomorphic type, but runST requires some polymorphism.
>
> If you want, you can use special type like that:
>
> data FoldSTVoid = FoldSTVoid {runFold :: forall a. (Int -> ST a ()) -> ST
> a ()}
>
> fold :: Monad m => (Int -> m ()) -> m ()
> fold f = mapM_ f [0..20]
>
> selectFold :: String -> IO FoldSTVoid -- ((Int -> m ()) -> m ())
> selectFold method = do
>     -- in real program I'd like to choose between
>     -- different fold methods, based on some IO context
>     return $ FoldSTVoid fold
>
> useFold :: FoldSTVoid -> ST a ()
> useFold fold' = runFold fold' f
>     where f _ = return () -- some trivial iterator
>
> main = do
>     fold'' <- selectFold "some-method-id"
>     print $ runST $ useFold fold''
>
> On Nov 28, 2012, at 9:52 PM, Dmitry Kulagin <dmitry.kulagin at gmail.com>
> wrote:
>
> > Hi Cafe,
> >
> > I try to implement some sort of monadic fold, where traversing is
> polymorphic over monad type.
> > The problem is that the code below does not compile. It works with any
> monad except for ST.
> > I suspect that monomorphism is at work here, but it is unclear for me
> how to change the code to make it work with ST.
> >
> > fold :: Monad m => (Int -> m ()) -> m ()
> > fold f = mapM_ f [0..20]
> >
> > selectFold :: Monad m => String -> IO ((Int -> m ()) -> m ())
> > selectFold method = do
> >     -- in real program I'd like to choose between
> >     -- different fold methods, based on some IO context
> >     return fold
> >
> > useFold :: Monad m => ((Int -> m ()) -> m ()) -> m ()
> > useFold fold' = fold' f
> >     where f _ = return () -- some trivial iterator
> >
> > main = do
> >     fold'' <- selectFold "some-method-id"
> >     print $ runST $ useFold fold''
> >
> >
> > Thank you!
> > Dmitry
> > _______________________________________________
> > Haskell-Cafe mailing list
> > Haskell-Cafe at haskell.org
> > http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20121129/c91d9a23/attachment.htm>


More information about the Haskell-Cafe mailing list