9

(m >>= f) >>= g = m >>= (\x -> f x >>= g)

what's different from f and \x->f x ??

I think they're the same type a -> m b. but it seems that the second >>= at right side of equation treats the type of \x->f x as m b. what's going wrong?

1 Answers1

15

The expressions f and \x -> f x do, for most purposes, mean the same thing. However, the scope of a lambda expression extends as far to the right as possible, i.e. m >>= (\x -> (f x >>= g)).

If the types are m :: m a, f :: a -> m b, and g :: b -> m c, then on the left we have (m >>= f) :: m b, and on the right we have (\x -> f x >>= g) :: a -> m c.

So, the difference between the two expressions is just which order the (>>=) operations are performed, much like the expressions 1 + (2 + 3) and (1 + 2) + 3 differ only in the order in which the additions are performed.

The monad laws require that, like addition, the answer should be the same for both.

C. A. McCann
  • 76,893
  • 19
  • 209
  • 302
  • 3
    Just a comment: `\x -> f x >>= g` is the same as `f >=> g`. (Kleisli fish) – fuz Dec 01 '11 at 20:54
  • 1
    @FUZxxl: Quite so! And to my eye, the relevant equivalence is considerably more elegant written that way. – C. A. McCann Dec 01 '11 at 20:57
  • 3
    In fact, the Typeclassopedia argues that this law is more elegantly stated in terms of `(>=>)`, recalling that that's basically composition. I as a learner agree. –  Dec 01 '11 at 21:00
  • 2
    @delnan: I'd sooner write them all that way; they're monoid laws with `(<=<)` as the operator and `return` as the identity, after all, so might as well make that obvious. – C. A. McCann Dec 01 '11 at 21:06
  • is this property associate to laziness? or just a exception? –  Dec 01 '11 at 21:18
  • where's (<=<) and (>=>) ? i tried.but both (<=<) and (>=>) are not in scope –  Dec 01 '11 at 21:24
  • @user20100: Not *inherently*, no. It's just a property, part of the definition of a monad, just as the associative property comes from the definition of addition. That said, laziness makes it much *easier* to define simple equivalences between expressions, which is why such properties aren't seen as often outside Haskell. – C. A. McCann Dec 01 '11 at 21:24
  • @user20100: [See here for the definition](http://hackage.haskell.org/packages/archive/base/4.4.1.0/doc/html/Control-Monad.html#v:-62--61--62-) of those operators. Import `Control.Monad` if you want them. As for what they do, see FUZxxl's comment; that's all there is to it. `(<=<)` is the same, just reversing the arguments. – C. A. McCann Dec 01 '11 at 21:25
  • @C. A. McCann: sorry for making misunderstanding. what property I said is "the second **>>=** at right side of equation treats the type of **\x->f x** as **m b**". in other words, does laziness make this **(\x -> f x >>= g) :: a -> m c** or not? –  Dec 01 '11 at 21:40
  • @user20100: It's how the syntax of Haskell works, that's all. Everything inside the parentheses is part of the lambda expression, not just the `f x`. The expression `\x -> f x` isn't relevant here because that's not how the compiler breaks the whole thing apart. – C. A. McCann Dec 01 '11 at 21:46
  • Using `>=>` or `<=<` requires that you have enabled the `-XChristianity` GHC extension. – Thomas Eding Dec 02 '11 at 21:39