Monad Usage – Why Use ‘Return’ or ‘Unit’ Instead of ‘Lift’?

design-patternshaskellmonad

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.

Best Answer

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.