Question

This is partly genuine curiosity, and partly a check on my understanding. I'm probably missing the point.

In Haskell, why does a monad use operations called return or unit to describe putting a type into the container -- lifting it into the monadic space? It seems more intuitive to call the operation lift.

Right now, in my (probably incorrect) port of monads into my own project, I'm using (pseudocode):

MyThing.lift(x).bind(f)...

rather than

MyThing.unit(x).bind(f)...

because it's more intuitive for me to think of lifting x into the monadic space.

Is that wrong-headed? I keep getting burned by not thinking abstractly enough, and I suspect that's the case again.

Was it helpful?

Solution

The term unit comes from category theory where we define a monad as two natural transformations unit : Identity ~> m and join : m x m ~> m. In case you're curious, bind f = join . fmap f.

return comes from do notation where return looks appropriately algol-ish. It's actually debatable whether this was a good name since it tends to suggest that return is some sort of control flow instead of just being a plain old function.

We usually reserve lift for things that are more like a functor and lift whole functions or monads. lift :: m a -> t m a and liftM :: (a -> b) -> m a -> m b.

OTHER TIPS

As Benjamin Hodgson mentioned in his comment, the term lift is usually applied to lifting non-monadic functions into the monad.

As for why the function is specifically called return, that is because it is used in the do syntactic sugar, which is meant to resemble an imperative C/ALGOL style code block, which typically used the return keyword to return a value.

Similarly, bind is called SelectMany in .NET, because its monad comprehensions are meant to resemble SQL queries.

Licensed under: CC-BY-SA with attribution
scroll top