Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With monads, can join be defined in terms of bind?

Tags:

haskell

monads

In Haskell, monads are defined in terms of the functions return and bind, where return has type a -> m a and bind has type m a -> (a -> m b) -> m b. It's been pointed out before that monads can also be defined in terms of return and join, where join is a function with type m (m a) -> m a. Bind can be defined in terms of join, but is the reverse possible? Can join be defined in terms of bind?

Without join, I have no idea what I'd do if I ever somehow got ahold of a "twice wrapped" monadic value, m (m a) - none of the functor or monad operations "remove any layers", so to speak. If this isn't possible, why do Haskell and many other monad implementations define them in terms of bind? It seems strictly less useful than a join-based definition.

like image 285
Jack Avatar asked Dec 21 '15 14:12

Jack


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”.

Where can you use monads?

monads are used to address the more general problem of computations (involving state, input/output, backtracking, ...) returning values: they do not solve any input/output-problems directly but rather provide an elegant and flexible abstraction of many solutions to related problems.

Are functions monads?

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.

Are lists monads?

List as a data structure is not a Monad, but the fact that Scala's List implements flatMap is what gives it its monadic super-powers. It also needs to fulfil associativity, left unit and right unit laws to qualify as a Monad.


1 Answers

It is possible:

join :: Monad m => m (m a) -> m a
join m = (m >>= id)

Note the tricky instantiation of >>=:

(>>=) :: m b -> (b -> m c) -> m c
-- choosing b ~ m a , c ~ a
(>>=) :: m (m a) -> (m a -> m a) -> m a

so we can correctly choose id for the second argument.

like image 84
chi Avatar answered Nov 16 '22 04:11

chi