Note that there are some explanatory texts on larger screens.

plurals
  1. POCovering all the cases of a promoted datatype
    text
    copied!<p>So I recently came up with this neat idea, in the hope of sharing code between the strict and lazy <code>State</code> transformer modules:</p> <pre><code>{-# LANGUAGE FlexibleInstances, DataKinds, KindSignatures #-} module State where data Strictness = Strict | Lazy newtype State (t :: Strictness) s a = State (s -&gt; (s, a)) returnState :: a -&gt; State t s a returnState x = State $ \s -&gt; (s, x) instance Monad (State Lazy s) where return = returnState State ma &gt;&gt;= amb = State $ \s -&gt; case ma s of ~(s', x) -&gt; runState (amb x) s' instance Monad (State Strict s) where return = returnState State ma &gt;&gt;= amb = State $ \s -&gt; case ma s of (s', x) -&gt; runState (amb x) s' get :: State t s s get = State $ \s -&gt; (s, s) put :: s -&gt; State t s () put s = State $ \_ -&gt; (s, ()) </code></pre> <p>You can see that <code>get</code> and <code>put</code> both work without any duplication – no type class instances, no anything – on both the strict and lazy types. However, even though I cover both possible cases for <code>Strictness</code>, I don't have a Monad instance for <code>State t s a</code> in general:</p> <pre><code>-- from http://blog.melding-monads.com/2009/12/30/fun-with-the-lazy-state-monad/ pro :: State t [Bool] () pro = do pro s &lt;- get put (True : s) -- No instance for (Monad (State t [Bool])) arising from a do statement </code></pre> <p>The following works fine, albeit requiring <code>FlexibleContexts</code>:</p> <pre><code>pro :: (Monad (State t [Bool])) =&gt; State t [Bool] () -- otherwise as before </code></pre> <p>Then I can instantiate <code>t</code> at <code>Lazy</code> or <code>Strict</code> and run the result and get what I expect. But why do I have to give that context? Is this a conceptual limitation, or a practical one? Is there some reason I'm missing why <code>Monad (State t s a)</code> actually doesn't hold, or is there just no way to convince GHC of it yet?</p> <p>(Aside: using the context <code>Monad (State t s)</code> <em>doesn't</em> work:</p> <blockquote> <p><code>Could not deduce (Monad (State t [Bool])) arising from a do statement</code> <code>from the context (Monad (State t s))</code></p> </blockquote> <p>which just confuses me even more. Surely the former is deducible from the latter?)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload