On Thu, Jan 1, 2009 at 2:30 PM, Jonathan Cast <jonathanccast@fastmail.fm> wrote:
On Thu, 2009-01-01 at 13:44 -0700, Luke Palmer wrote:
> On Thu, Jan 1, 2009 at 1:31 PM, David Menendez <dave@zednenem.com>
> wrote:
>         2009/1/1 Luke Palmer <lrpalmer@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 }
>
> I have heard this called the "codensity monad" (and it appears under
> that name in category-extras).  Good observation.
>
> In my reply I missed the important consideration of the strictness of
> (>>=), irrsepective of the values.  While you can not force values to
> be strict in a monad without breaking a law, (>>=) is "up for grabs",

Is it?  By the second monad law, (>>= return) is required to be strict.
return must not be strict, as observed above.  Are there monads which
satisfy both laws, but have undefined >>= f /= undefined, for some f?  I
suspect (although I don't seem to have the source on my computer atm)
that Control.Monad.State.{Lazy,Strict} both cheat on the second monad
law anyway, though...

ghci> import Control.Monad.Writer
ghci> head . getDual . execWriter $ undefined >> tell (Dual [42])
42

Luke