You&#39;re right. It must be &quot;data&quot; not &quot;newtype&quot;. I first wrote it with &quot;data&quot;, but then I consider using &quot;newtype&quot; instead, as the identity monad does, and the fact that the transformer worked right with &quot;newtype&quot; got me confused. After some tests I finally realised that whenever you use &quot;newtype&quot; in your underlying monad then the transformer gives something which is not a monad.<br>
<br>The problem (I think) is as follows: If you write a transformer which turns your monads into strict ones, then it may give something which is not a monad for some particular strict monads. If you relax your trasnformer in order to always have a monad, then it won&#39;t be strict for some particular lazy monads. Is the same old problem lifted to the transformers world. Does this intuition make any sense? I&#39;m always referring to using Haskell strict primitives, not CPS.<br>
<br>Alvaro.<br><br><div class="gmail_quote">El 5 de noviembre de 2009 06:19, Ryan Ingram <span dir="ltr">&lt;<a href="mailto:ryani.spam@gmail.com" target="_blank">ryani.spam@gmail.com</a>&gt;</span> escribió:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">2009/11/4 Álvaro García Pérez &lt;<a href="mailto:agarcia@babel.ls.fi.upm.es" target="_blank">agarcia@babel.ls.fi.upm.es</a>&gt;:<br>


<div><div></div><div>&gt; Hi,<br>
&gt;<br>
&gt; I&#39;m trying to characterise some strict monads to work with a particular<br>
&gt; lambda-calculus evaluator, as an alternative to CPS monad.<br>
&gt;<br>
&gt; In the thread &quot;Stupid question #852: Strict monad&quot; the implementation of<br>
&gt; some strict monads (and pseudo-monads, not meeting the identity laws) is<br>
&gt; discussed. It&#39;s clear form that thread that using pattern-matching in the<br>
&gt; (&gt;&gt;=) operation will force evaluation, then the Id monad defined with<br>
&gt; pattern-matching is strict (and it&#39;s indeed a monad):<br>
&gt;<br>
&gt;&gt; newtype Id a = Id a<br>
&gt;&gt;<br>
&gt;&gt; instance Monad Id where<br>
&gt;&gt;     return = Id<br>
&gt;&gt;     (Id a) &gt;&gt;= f = f a<br>
&gt;<br>
&gt; But it&#39;s impossible to derive a monad transformer from it, because you don&#39;t<br>
&gt; know the constructors of the monads you&#39;re transforming. I then tried to use<br>
&gt; strict application ($!). My first attempt was<br>
&gt;<br>
&gt;&gt; newtype Strict a = InSt { outSt :: a }<br>
&gt;&gt;<br>
&gt;&gt; instance Monad Strict where<br>
&gt;&gt;     return = InSt<br>
&gt;&gt;     m &gt;&gt;= f = (\x -&gt; fDoes this make sense, or am I  wrong intuition? x) $! (outSt m)<br>
&gt;<br>
&gt; which is not a monad (doesn&#39;t meet the left identity law).<br>
&gt;<br>
&gt;     (return undefined) &gt;&gt;= (\x -&gt; const (return 1) x)<br>
&gt; =/=        (return 1)<br>
&gt;<br>
&gt; Then I wondered if it was enough to force the evaluation of the whole monad,<br>
&gt; instead of the value inside the monad, yielding the second attempt:<br>
&gt;<br>
&gt;&gt; newtype Strict a = InSt { outSt :: a }<br>
&gt;&gt;<br>
&gt;&gt; instance Monad Strict where<br>
&gt;&gt;     return = InSt<br>
&gt;&gt;     m &gt;&gt;= f = (\x -&gt; f (outSt x)) $! m<br>
&gt;<br>
&gt; I placed the outSt inside the anonymous function, leaving the monad on the<br>
&gt; right of the ($!). This meets the identity laws and surprisingly (I was<br>
&gt; expecting a lazy behaviour) implements strict semantics (it behaves like<br>
&gt; CPS, which is strict as well). A transformer from this monad can be easily<br>
&gt; written:<br>
<br>
</div></div>This seems like it has the same problem to me:<br>
<br>
return undefined &gt;&gt;= const return 1<br>
= InSt undefined &gt;&gt;= const return 1<br>
= (\x -&gt; (const return 1) (outSt x)) $! (InSt undefined)<br>
= let y = InSt undefined in seq y ((\x -&gt; (const return 1) (outSt x)) y)<br>
= undefined -- since InSt is a newtype.<br>
<br>
You would get different behavior with<br>
<br>
data InStD a = InStD a<br>
<br>
which puts another element in the domain:<br>
<br>
InSt () contains<br>
[_|_, InSt ()] only<br>
<br>
whereas InStD () contains<br>
[_|_, InStD _|_, InStD ()]<br>
<font color="#888888"><br>
  -- ryan<br>
</font></blockquote></div><br>