Thank you, MigMit!<div><br></div><div>If I replace your type FoldSTVoid with:</div><div><div>data FoldMVoid = FoldMVoid {runFold :: Monad m =&gt; (Int -&gt; m ()) -&gt; m ()}</div></div><div><br></div><div>then everything works magically with any monad!</div>

<div>That is exactly what I wanted, though I still do not quite understand why wrapping the type solves the problem</div><div><br></div><div>Dmitry</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Nov 29, 2012 at 12:01 AM, MigMit <span dir="ltr">&lt;<a href="mailto:miguelimo38@yandex.ru" target="_blank">miguelimo38@yandex.ru</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Yes, monomorphism. &quot;do&quot; binding requires your fold&#39;&#39; to be of some monomorphic type, but runST requires some polymorphism.<br>


<br>
If you want, you can use special type like that:<br>
<br>
data FoldSTVoid = FoldSTVoid {runFold :: forall a. (Int -&gt; ST a ()) -&gt; ST a ()}<br>
<div class="im"><br>
fold :: Monad m =&gt; (Int -&gt; m ()) -&gt; m ()<br>
fold f = mapM_ f [0..20]<br>
<br>
</div>selectFold :: String -&gt; IO FoldSTVoid -- ((Int -&gt; m ()) -&gt; m ())<br>
<div class="im">selectFold method = do<br>
  -- in real program I&#39;d like to choose between<br>
  -- different fold methods, based on some IO context<br>
</div>  return $ FoldSTVoid fold<br>
<br>
useFold :: FoldSTVoid -&gt; ST a ()<br>
useFold fold&#39; = runFold fold&#39; f<br>
<div class="im">  where f _ = return () -- some trivial iterator<br>
<br>
main = do<br>
  fold&#39;&#39; &lt;- selectFold &quot;some-method-id&quot;<br>
  print $ runST $ useFold fold&#39;&#39;<br>
<br>
</div><div><div class="h5">On Nov 28, 2012, at 9:52 PM, Dmitry Kulagin &lt;<a href="mailto:dmitry.kulagin@gmail.com">dmitry.kulagin@gmail.com</a>&gt; wrote:<br>
<br>
&gt; Hi Cafe,<br>
&gt;<br>
&gt; I try to implement some sort of monadic fold, where traversing is polymorphic over monad type.<br>
&gt; The problem is that the code below does not compile. It works with any monad except for ST.<br>
&gt; 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.<br>
&gt;<br>
&gt; fold :: Monad m =&gt; (Int -&gt; m ()) -&gt; m ()<br>
&gt; fold f = mapM_ f [0..20]<br>
&gt;<br>
&gt; selectFold :: Monad m =&gt; String -&gt; IO ((Int -&gt; m ()) -&gt; m ())<br>
&gt; selectFold method = do<br>
&gt;   -- in real program I&#39;d like to choose between<br>
&gt;   -- different fold methods, based on some IO context<br>
&gt;   return fold<br>
&gt;<br>
&gt; useFold :: Monad m =&gt; ((Int -&gt; m ()) -&gt; m ()) -&gt; m ()<br>
&gt; useFold fold&#39; = fold&#39; f<br>
&gt;   where f _ = return () -- some trivial iterator<br>
&gt;<br>
&gt; main = do<br>
&gt;   fold&#39;&#39; &lt;- selectFold &quot;some-method-id&quot;<br>
&gt;   print $ runST $ useFold fold&#39;&#39;<br>
&gt;<br>
&gt;<br>
&gt; Thank you!<br>
&gt; Dmitry<br>
</div></div>&gt; _______________________________________________<br>
&gt; Haskell-Cafe mailing list<br>
&gt; <a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
&gt; <a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
<br>
</blockquote></div><br></div>