
The type signature of bind (>>=) is as follows: (>>=) :: m a -> (a -> m b) -> m b One interpretation of this could be as follows: bind takes two parameters (m a & f) and returns m b (the same type returned by f) So extending this interpretation - can I swap the two parameters (?) Now my new hypothetical interpretation becomes: (>>=) :: (a -> m b) -> m a -> m b If i further add parens: (>>=) (a -> m b) -> (m a -> m b) This allows me to slightly tweak my interpretation: bind takes one param f (of type a -> m b) and returns another param f (of type m a -> m b) This feels like a more intuitive way to think about Monads - am I on the right track? (not that I want to switch the params permanently - just trying to get a feel for monads)

On 14/12/2015, Raja
So extending this interpretation - can I swap the two parameters (?)
Now my new hypothetical interpretation becomes:
(>>=) :: (a -> m b) -> m a -> m b
Sure, bind' :: Monad m => (a -> m b) -> m a -> m b bind' = flip (>>=)
If i further add parens:
(>>=) :: (a -> m b) -> (m a -> m b)
Yeah, that's exactly the same thing. Types are right associative.

This function is actually in the Prelude as (=<<).
On Mon, 14 Dec 2015, 13:17 Dániel Arató
On 14/12/2015, Raja
wrote: So extending this interpretation - can I swap the two parameters (?)
Now my new hypothetical interpretation becomes:
(>>=) :: (a -> m b) -> m a -> m b
Sure, bind' :: Monad m => (a -> m b) -> m a -> m b bind' = flip (>>=)
If i further add parens:
(>>=) :: (a -> m b) -> (m a -> m b)
Yeah, that's exactly the same thing. Types are right associative. _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Yeah, after my first couple of significant Haskell projects I came to the
conclusion that having (>>=) instead of (=<<) as the "canonical bind" is a
wart. (>>=) makes for clean desugaring of do notation, but obscures that (a
-> m b) -> (m a -> m b) intuition, which I think is more important
pedagogically and also tends to be cleaner in non-do monadic code.
To a beginner, flip is an easy mechanical concept, but analyzing the
resultant type for new insights is not a habit yet. The one whose purpose
is purely mechanical should be "the flipped one."
On Dec 14, 2015 10:41 AM, "Joel Williamson"
This function is actually in the Prelude as (=<<).
On Mon, 14 Dec 2015, 13:17 Dániel Arató
wrote: On 14/12/2015, Raja
wrote: So extending this interpretation - can I swap the two parameters (?)
Now my new hypothetical interpretation becomes:
(>>=) :: (a -> m b) -> m a -> m b
Sure, bind' :: Monad m => (a -> m b) -> m a -> m b bind' = flip (>>=)
If i further add parens:
(>>=) :: (a -> m b) -> (m a -> m b)
Yeah, that's exactly the same thing. Types are right associative. _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Raja
Now my new hypothetical interpretation becomes:
(>>=) :: (a -> m b) -> m a -> m b
You have independently discovered (=<<), which is excellent news!
If i further add parens:
(>>=) (a -> m b) -> (m a -> m b)
This allows me to slightly tweak my interpretation:
bind takes one param f (of type a -> m b) and returns another param f (of type m a -> m b)
This feels like a more intuitive way to think about Monads - am I on the right track? (not that I want to switch the params permanently - just trying to get a feel for monads)
Yes, you are absolutely on the right track. One way to interpret bind is as a particular way to abstract function application. Consider these types: ($) :: (a -> b) -> a -> b (<$>) :: Functor f => (a -> b) -> f a -> f b (=<<) :: Monad m => (a -> m b) -> m a -> m b All of them take a particular type of function and "lift" it to apply to a particular type of value. ($) performs an "identity lift", which is to say that it does no lifting at all[1]. (<$>), aka fmap, lifts functions to apply "in" a Functor "context". (=<<) lifts functions (of a certain type) to apply in a Monad context. (The ability to talk about these sorts of abstract functions is one of the motivations of Category Theory, not that you need to know CT to do Haskell.) Note also that these are listed in strictly increasing order of expressiveness, which is to say that a later operator can do anything that an earlier operator can do, but not vice versa[2]. If you explore exactly what (=<<) can do that fmap cannot, you may learn something else about monads! [1]: By the way, you can also define ($) as id. id f = f is exactly the "identity lift" that I am taliking about! Using your "add parens" interpretation, ($) takes an (a -> b) and gives an (a -> b) (the same one you gave it). [2]: As long as you admit that Identity x is equivalent to x.
participants (5)
-
Dániel Arató
-
Joel Williamson
-
Raja
-
Rein Henrichs
-
Theodore Lief Gannon