1

When reading code, I like to be able to form sentences in my head. For example, x <- getChar could be something like "x slurps getChar". Or a . b would be "b applied to a".

But when it comes to the Monadic Bind operator f >>= g, I just leave a mental gap in the sentence in my head, because I don't know how to read it. I thought about "f binds g", but that feels wrong. What suggestions do you have?

The proposed duplicate link contains some really nice answers for other operators, but for the bind operator the answers just say "bind". However, "f bind g" doesn't seem meaningful to me.

lucidbrot
  • 5,378
  • 3
  • 39
  • 68
  • 6
    In some sense, it depends on the specific monad in question, but reading bind as “and then” tends to work alright. Of course, both your “correct” examples are somewhat wrong, since `x <- getChar` is no different from `getChar >>= \x -> ...` and `a . b` is composition, not application. – Alexis King Apr 07 '17 at 06:28
  • 3
    Possible duplicate of [Are there pronounceable names for common Haskell operators?](http://stackoverflow.com/questions/7746894/are-there-pronounceable-names-for-common-haskell-operators) – jub0bs Apr 07 '17 at 06:29
  • 1
    @Jubobs Thanks for that "possible duplicate" link! it is really helpful but it seems to me that for the bind operator, it does not offer a good answer. I'll try to explain why I think so in an edit :) – lucidbrot Apr 07 '17 at 06:36
  • @AlexisKing I like your proposal "and then". What do you mean is wrong about my example with getChar? – lucidbrot Apr 07 '17 at 06:39
  • 1
    Words and concepts are related. How would you rate your understanding of monad as a concept? It may be that "f bind g" will start feeling more meaningful as you get more comfortable in your understanding. – luqui Apr 07 '17 at 06:44
  • @luqui I've been studying the concept of Applicative Functors and Monads only since last week, so you may be right. I believe I understand what the bind operator does, but as the content of the Monad `f` is "put" into the function `g`, it feels more intuitive to me that "g binds f". But reading from right to left is probably not the best solution – lucidbrot Apr 07 '17 at 06:49
  • maybe you're right and I can just try to use `f bind g` until it becomes a meaningful word for me – lucidbrot Apr 07 '17 at 07:07
  • 1
    I definitely wouldn't read `a . b` as “`b` applied to `a`”. That would be `b a`. It's just _`a` composed with `b`_, or perhaps _`a` after `b`_. – leftaroundabout Apr 07 '17 at 08:24
  • [There](https://wiki.haskell.org/Pronunciation) is a page on haskellwiki about pronuncation. – wizzup Apr 07 '17 at 08:27
  • @leftaroundabout what would you say to "the result of b applied to a"? – lucidbrot Apr 07 '17 at 08:32
  • 1
    The other way around, _`a` applied to the result of `b`_. But that would mean there are actually _values_ around, i.e. it would more correspond to `a $ b x`. – leftaroundabout Apr 07 '17 at 08:49
  • @leftaroundabout oh, yes I see my mistake. Thanks :) – lucidbrot Apr 07 '17 at 11:44
  • I have recently seen someone suggest "`f` from `x`" for `f =<< x`. I kind of like it, though I can't quite see an analogue for `>>=` which wouldn't be annoyingly ambiguous. – duplode Apr 08 '17 at 06:40

3 Answers3

2

Names of >>= for monad-like constructs of other languages:

  • For Javascript promises, it is then. (Not a perfect correspondence though, because then does more things.)
  • For Java Optionals and Streams, it is flatMap (They are similarly named functions, but they don't come from the same interface.)
  • For Java's CompletableFuture, it is thenComposeAsync.

>>= is equivalent to first mapping with an effectful function

fmap putStrLn getLine :: IO (IO ())

and then "fusing" the two nested layers of the type constructor with join :: Monad m => m (m a) -> m a:

join (fmap putStrLn getLine) :: IO ()

So how about calling it "map 'n fuse"?

danidiaz
  • 26,936
  • 4
  • 45
  • 95
  • 1
    As another data point, LINQ [calls it `SelectMany`](https://msdn.microsoft.com/en-us/library/bb534336(v=vs.110).aspx), which makes sense in context (its `fmap` analogue is called `Select`) but isn't very illuminating for our purposes. – duplode Apr 08 '17 at 06:23
1

I would suggest thinking of the word 'bind' in the sense of 'attach': binding g to f means attaching a monadic action g to the monad f. To flesh this out a bit, think of f, a monad, as a computation which, when run, will return some value (call this value x). Binding a monadic action g to a monad f expresses a new computation in which the monadic action g is now attached to the monad f, in the sense that the result (x) of the monadic computation f is to be passed along as an argument to the action g, which in turn returns a new (monadic) computation.

liminalisht
  • 1,243
  • 9
  • 11
  • [1/2] This makes intuitive sense, though the terminology is a bit backwards with respect to how we usually call things in Haskell. It is better to call the `f` in `f >>= g` a "monadic value", "computation" or "action", and not "monad" -- the monad proper is the type constructor and/or its `Monad` instance. As for the `g` function, there is "Kleisli arrow" if you want a specific term, but simply "the `a -> m b` function" will work fine in most contexts. – duplode Apr 08 '17 at 06:06
  • 1
    [2/2] The "bind" name reflects that in `f >>= \x -> g x` (i.e. `do { x <- f; g x }`) we bind the result(s) of `f` to the variable `x`, so that we can refer to it in what follows. – duplode Apr 08 '17 at 06:13
  • @duplode I agree w/ everything you said. Re your second comment: yes, the term 'bind' is so named b/c of the variable binding going on in your example above, and that would go a long way toward explaining reading `x <- f` as `x` is bound to the result of `f`, but there's still some cognitive disconnect b/t understanding that, and understanding `f >>= g` as `f` bind `g`. – liminalisht Apr 08 '17 at 13:03
1

Elm uses andThen which is equivalent to >>=

makeThingA >>= (\a -> consumeThing a)

aka

makeThingA `andThen` (\a -> consumeThing a)
William Casarin
  • 2,542
  • 2
  • 23
  • 24