
2009/1/1 Luke Palmer
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