Is my understanding of ">>=" correct?

Hello all, It took me quite some time to understand >>=. What confused me, was that the second operand is a function, not just a Monad. I believe I am beginning to see the light. First there is no way to sequence operations by just writing one after the other. However we can chain operations by passing the output of one operation to the next. But this does not not allow capturing the intermediate results. With >>= the output of one operation gets magically bound to the parameter of the function and remains in scope all the way through. I was confused by the signature m a -> (a -> mb) -> mb because it looks like there is (as second parameter) a function which returns a Monad. But I doubt I ever saw such a function, in the sense that it does something intelligent. It is typically a function that does not do a whole lot with its parameter, but just returns another Monad, such that its parameter is bound to the result of the previous expression. But it could be done: do x <- SomeMonad y <- someCleverlyConstructedMonad x If I want to see the function of the >>= signature I have to read the do block right->left (following the arrow) and then diagonally to the lower right. The diagonal steps reveal the function. In the above example we have \x -> someCleverlyConstructedMonad but many times I just see do x <- SomeMonad y <- someOtherMonad and the function does not do anything intelligent but just binds x and enforces the sequence of operations. is this about right? -- Martin

On Tue, Feb 19, 2013 at 11:13 AM, Martin Drautzburg < Martin.Drautzburg@web.de> wrote:
Hello all,
It took me quite some time to understand >>=. What confused me, was that the second operand is a function, not just a Monad. I believe I am beginning to see the light.
First there is no way to sequence operations by just writing one after the other. However we can chain operations by passing the output of one operation to the next. But this does not not allow capturing the intermediate results. With >>= the output of one operation gets magically bound to the parameter of the function and remains in scope all the way through.
Well, sequencing actions is a special case of chaining actions where you simply ignore the result of the previous action. This is the >> operator. It is defined as follows: m >> k = m >>= \_ -> k There is no magic involved, just functions and lexically scoped variables. I was confused by the signature m a -> (a -> mb) -> mb because it looks like
there is (as second parameter) a function which returns a Monad. But I doubt I ever saw such a function, in the sense that it does something intelligent. It is typically a function that does not do a whole lot with its parameter, but just returns another Monad, such that its parameter is bound to the result of the previous expression.
I think it's important to note that the signature is a -> (a -> m b) -> m b. The space is significant. 'm' is a separate type variable from 'a' or 'b'.
But it could be done:
do x <- SomeMonad y <- someCleverlyConstructedMonad x
If I want to see the function of the >>= signature I have to read the do block right->left (following the arrow) and then diagonally to the lower right. The diagonal steps reveal the function. In the above example we have
\x -> someCleverlyConstructedMonad
but many times I just see
do x <- SomeMonad y <- someOtherMonad
and the function does not do anything intelligent but just binds x and enforces the sequence of operations.
is this about right?
It's not really possible to translate the above example into valid code because a do block must end with an expression. Let's say you were to change it to the following valid syntax: do x <- firstAction y <- secondAction x return (x, y) The de-sugaring of that do block would look like this (newlines added to show function scope): firstAction >>= \x -> secondAction x >>= \y -> return (x, y) A concrete example: do x <- getLine y <- print x return (x, y) h> getLine >>= \x -> print x >>= \y -> return (x, y) Hello! "Hello!" ("Hello!",()) do blocks are just syntax sugar, they don't do anything you couldn't easily do with 'let ... in', '>>=' and '->'. They just make it a lot easier to read in some cases. Other cases it's a wash, such as in this example where we don't want to capture any intermediate results: do x <- getLine print x is equivalent to: getLine >>= print -bob

Hi, I tried to explain Haskell IO in an introductory talk. Slides are available here: http://www.sylvain-henry.info/home/data/uploads/teaching/shenry-slides-haske... You may find the "Real World Haskell" section interesting to understand monads. I use explicit World variables to explain how operations are sequenced. It helped me to think about it this way when I learned it. Cheers Sylvain Le 19/02/2013 20:13, Martin Drautzburg a écrit :
Hello all,
It took me quite some time to understand >>=. What confused me, was that the second operand is a function, not just a Monad. I believe I am beginning to see the light.
First there is no way to sequence operations by just writing one after the other. However we can chain operations by passing the output of one operation to the next. But this does not not allow capturing the intermediate results. With >>= the output of one operation gets magically bound to the parameter of the function and remains in scope all the way through.
I was confused by the signature m a -> (a -> mb) -> mb because it looks like there is (as second parameter) a function which returns a Monad. But I doubt I ever saw such a function, in the sense that it does something intelligent. It is typically a function that does not do a whole lot with its parameter, but just returns another Monad, such that its parameter is bound to the result of the previous expression.
But it could be done:
do x <- SomeMonad y <- someCleverlyConstructedMonad x
If I want to see the function of the >>= signature I have to read the do block right->left (following the arrow) and then diagonally to the lower right. The diagonal steps reveal the function. In the above example we have
\x -> someCleverlyConstructedMonad
but many times I just see
do x <- SomeMonad y <- someOtherMonad
and the function does not do anything intelligent but just binds x and enforces the sequence of operations.
is this about right?
participants (3)
-
Bob Ippolito
-
Martin Drautzburg
-
Sylvain HENRY