[Haskell-cafe] Stupid question #852: Strict monad

David Menendez dave at zednenem.com
Thu Jan 1 15:31:13 EST 2009


2009/1/1 Luke Palmer <lrpalmer at gmail.com>:
>
> So that's the answer: there already is a Strict monad.  And an attempt to
> make a lazier one strict just results in breaking the monad laws.

There is at least one transformer that will make a strict monad out of
a non-strict monad.

newtype CPS m a = CPS { unCPS :: forall b. (a -> m b) -> m b }

instance Monad (CPS m) where
    return x = CPS (\k -> k x)
    m >>= f = CPS (\k -> unCPS m (\a -> unCPS (f a) k))

toCPS :: Monad m => m a -> CPS m a
toCPS m = CPS (\k -> m >>= k)

fromCPS :: Monad m => CPS m a -> m a
fromCPS m = unCPS m return

Contrast:

> runIdentity $ undefined >>= \_ -> return ()
()

> runIdentity . fromCPS $ undefined >>= \_ -> return ()
*** Exception: Prelude.undefined

> There's another answer though, regarding your question for why we don't just
> use StrictT State instead of a separate State.Strict.  This message is
> already too long, and I suspect this will be the popular reply anyway, but
> the short answer is that Strict State is called that because it is strict in
> its state, not in its value.

No, Control.Monad.State.Strict and Control.Monad.State.Lazy never
force evaluation of their states.

Control.Monad.State.Strict> evalState (put undefined) '0'
()

The difference is in the strictness of (>>=).

The same is true of the other Strict/Lazy pairs.

-- 
Dave Menendez <dave at zednenem.com>
<http://www.eyrie.org/~zednenem/>


More information about the Haskell-Cafe mailing list