Hello,<br><br>I am trying to make a monad that uses ST internally.<br>But even when reducing this to the simplest case I&#39;m still cramped by the &#39;s&#39; phantom type :<br><br><span style="font-family: courier new,monospace;">{-# LANGUAGE Rank2Types #-}</span><br style="font-family: courier new,monospace;">

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">newtype MyST a = MyST (forall s. ST s a)</span><br style="font-family: courier new,monospace;">-- ^ I cannot use &quot; deriving (Monad) &quot; through GeneralizedNewtypeDeriving<br>

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">runMyST (MyST m) = runST m</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">-- ^ works thanks to declaration of &#39;s&#39; at rank 2 in the definition of MyST</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">--   It refuses to compile if MyST is declared as such:</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">--   data MyST s a = MyST (ST s a)</span><br style="font-family: courier new,monospace;">

<br><span style="font-family: courier new,monospace;">instance Monad MyST where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">  return = MyST . return           -- and this does not compile</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">  (MyST m) &gt;&gt;= f = MyST $ do</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    x &lt;- m</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">    case f x of</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">      (MyST m) -&gt; m</span><br style="font-family: courier new,monospace;">

<br><br>If you try it, GHC will complain:<br>Simple.hs:13:20:<br>    Couldn&#39;t match expected type `forall s. ST s a&#39;<br>                with actual type `ST s a&#39;<br>    Expected type: a -&gt; forall s1. ST s1 a<br>

      Actual type: a -&gt; ST s a<br>    In the second argument of `(.)&#39;, namely<br>      `(return :: a -&gt; (forall s. ST s a))&#39;<br>    In the expression: MyST . (return :: a -&gt; (forall s. ST s a))<br>