
On Thu, 2009-01-01 at 14:25 -0500, Brian Hurt wrote:
First off, let me apologize for this ongoing series of stupid newbie questions. Haskell just recently went from that theoretically interesting language I really need to learn some day to a language I actually kinda understand and can write real code in (thanks to Real World Haskell). Of course, this gives rise to a whole bunch of "wait- why is it this way?" sort of questions.
So today's question is: why isn't there a Strict monad? Something like:
data Strict a = X a
(Note that you can eliminate the `seq`s below by saying data Strict a = X !a instead, or, if X is going to be strict, newtype Strict a = X a).
instance Monad Strict where ( >>= ) (X m) f = let x = f m in x `seq` (X x) return a = a `seq` (X a)
(although this code doesn't compile for reasons I'm not clear on- I keep getting: temp.hs:4:0: Occurs check: cannot construct the infinite type: b = Strict b When trying to generalise the type inferred for `>>=' Signature type: forall a b1. Strict a -> (a -> Strict b1) -> Strict b1 Type to generalise: forall a b1. Strict a -> (a -> Strict b1) -> Strict b1 In the instance declaration for `Monad Strict' as a type error. Feel free to jump in and tell me what I'm doing wrong.)
Since you asked, The simplest fix (that makes the code you posted compile) is to pattern match on the result of f (to do what you want): (>>=) (X m) f = let X x = f m in x `seq` X x (I would write X m >>= f = let X x = f m in X $! x) But unless you export the X constructor (and don't make it strict), then f should never return (X undefined), so the above is equivalent, for all f in practice, to X m >>= f = f m I think what you really want to say is newtype Strict alpha = X alpha instance Monad Strict where return = X X x >>= f = f $! x jcc