<div>Hi,</div>
<div> </div>
<div>I&#39;m trying to characterise some strict monads to work with a particular lambda-calculus evaluator, as an alternative to CPS monad.</div>
<div> </div>
<div>In the thread &quot;Stupid question #852: Strict monad&quot; the implementation of some strict monads (and pseudo-monads, not meeting the identity laws) is discussed. It&#39;s clear form that thread that using pattern-matching in the (&gt;&gt;=) operation will force evaluation, then the Id monad defined with pattern-matching is strict (and it&#39;s indeed a monad):</div>


<div> </div>
<div>&gt; newtype Id a = Id a<br>&gt;<br></div>
<div>&gt; instance Monad Id where</div>
<div>&gt;     return = Id</div>
<div>&gt;     (Id a) &gt;&gt;= f = f a</div>
<div> </div>
<div>But it&#39;s impossible to derive a monad transformer from it, because you don&#39;t know the constructors of the monads you&#39;re transforming. I then tried to use strict application ($!). My first attempt was</div>


<div> </div>
<div>&gt; newtype Strict a = InSt { outSt :: a }<br>&gt;<br></div>
<div>&gt; instance Monad Strict where</div>
<div>&gt;     return = InSt</div>
<div>&gt;     m &gt;&gt;= f = (\x -&gt; f x) $! (outSt m)</div>
<div> </div>
<div>which is not a monad (doesn&#39;t meet the left identity law).</div>
<div> </div>
<div>    (return undefined) &gt;&gt;= (\x -&gt; const (return 1) x)         =/=        (return 1)</div>
<div> </div>
<div>Then I wondered if it was enough to force the evaluation of the whole monad, instead of the value inside the monad, yielding the second attempt:<br><br>&gt; newtype Strict a = InSt { outSt :: a }<br>&gt;<br>&gt; instance Monad Strict where<br>
&gt;     return = InSt<br>&gt;     m &gt;&gt;= f = (\x -&gt; f (outSt x)) $! m<br><br>I placed the outSt inside the anonymous function, leaving the monad on the right of the ($!). This meets the identity laws and surprisingly (I was expecting a lazy behaviour) implements strict semantics (it behaves like CPS, which is strict as well). A transformer from this monad can be easily written:<br>
<br>&gt; newtype StrictT m a = InStT { outStT :: m a }<br>&gt;<br>&gt; instance Monad m =&gt; Monad (StrictT m) where<br>&gt;     return = InStT . return<br>&gt;     m &gt;&gt;= t = InStT $ (\x -&gt; x &gt;&gt;= (\a -&gt; outStT $ t a)) $! (outStT m)<br>
&gt;<br>&gt; instance MonadTrans StrictT where<br>&gt;     lift = InStT<br><br>Is it common practice to use this monad and this transformer? Why is it not in the standard library? I looked for this monad in the literature but I didn&#39;t find anything similar. It seems naive to me that this has never been previously described. Am I doing something wrong and this is not a monad at all?<br>
<br>Alvaro.<br></div>