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@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@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@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe