Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is monad bind (>>=) operator closer to function composition (chaining) or function application?

Tags:

In many articles I have read that monad >>= operator is a way to represent function composition. But for me it is closer to some kind of advanced function application

($)   :: (a -> b) -> a -> b (>>=) :: Monad m => m a -> (a -> m b) -> m b 

For composition we have

(.)   :: (b -> c) -> (a -> b) -> a -> c (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c 

Please clarify.

like image 963
Sergii Vorobei Avatar asked Dec 31 '15 11:12

Sergii Vorobei


People also ask

What is monad bind?

Monadic bind is the name given to the (>>=) function or bind function, also known as chain, flatMap, or joinMap. I personally like to call it the “then” function borrowing the word from JavaScript Promises. It is much more intuitive that way if you read it as “then” instead of “bind”.

Is a monad a function?

In functional programming, a monad is a software design pattern with a structure that combines program fragments (functions) and wraps their return values in a type with additional computation.

What is monad simple explanation?

A monad is an algebraic structure in category theory, and in Haskell it is used to describe computations as sequences of steps, and to handle side effects such as state and IO. Monads are abstract, and they have many useful concrete instances. Monads provide a way to structure a program.

What are monadic operations?

monadic operation (unary operation) defined on a set S. A function from the domain S into S itself. The identity function is a monadic operation. Other examples are the operations of negation in arithmetic or logic and of taking complements in set theory or in Boolean algebra.


1 Answers

Clearly, >>= is not a way to represent function composition. Function composition is simply done with .. However, I don't think any of the articles you've read meant this, either.

What they meant was “upgrading” function composition to work directly with “monadic functions”, i.e. functions of the form a -> m b. The technical term for such functions is Kleisli arrows, and indeed they can be composed with <=< or >=>. (Alternatively, you can use the Category instance, then you can also compose them with . or >>>.)

However, talking about arrows / categories tends to be confusing especially to beginners, just like point-free definitions of ordinary functions are often confusing. Luckily, Haskell allows us to express functions also in a more familiar style that focuses on the results of functions, rather the functions themselves as abstract morphisms. It's done with lambda abstraction: instead of

q = h . g . f 

you may write

q = (\x -> (\y -> (\z -> h z) (g y)) (f x)) 

...of course the preferred style would be (this being only syntactic sugar for lambda abstraction!)&ddagger;

q x = let y = f x           z = g y       in h z 

Note how, in the lambda expression, basically composition was replaced by application:

q = \x -> (\y -> (\z -> h z) $ g y) $ f x 

Adapted to Kleisli arrows, this means instead of

q = h <=< g <=< f 

you write

q = \x -> (\y -> (\z -> h z) =<< g y) =<< f x 

which again looks of course much nicer with flipped operators or syntactic sugar:

q x = do y <- f x          z <- g y          h z 

So, indeed, =<< is to <=< like $ is to .. The reason it still makes sense to call it a composition operator is that, apart from “applying to values”, the >>= operator also does the nontrivial bit about Kleisli arrow composition, which function composition doesn't need: joining the monadic layers.


The reason this works is that Hask is a cartesian closed category, in particular a well-pointed category. In such a category, arrows can, broadly speaking, be defined by the collection of all their results when applied to simple argument values.

&ddagger;@adamse remarks that let is not really syntactic sugar for lambda abstraction. This is particularly relevant in case of recursive definitions, which you can't directly write with a lambda. But in simple cases like this here, let does behave like syntactic sugar for lambdas, just like do notation is syntactic sugar for lambdas and >>=. (BTW, there's an extension which allows recursion even in do notation... it circumvents the lambda-restriction by using fixed-point combinators.)

like image 136
leftaroundabout Avatar answered Oct 05 '22 22:10

leftaroundabout