Lifting like this is one of the most useful ideas I have taken from Haskell, but I think it's hard to see its utility through the C++. At it's core, lifting allows functions that don't require a computational context to be composed with values and functions that have a computational context. For instance, `unwords . reverse . words` is a function from Strings to Strings and is used like
unwords . reverse . words $ "The quick brown fox" => "fox brown quick The"
or
(unwords . reverse . words) "The quick brown fox" => "fox brown quick The".
This is just a pure deterministic function mapping values to values, it has no special context. To compose it with a value with a context like strings may not be present (Maybe String), it can be lifted with fmap (which really would be more informatively named liftF to keep with the Haskell lift function naming scheme).
fmap (unwords . reverse . words) (Just "The quick brown fox") => Just "fox brown quick The"
fmap (unwords . reverse . words) Nothing => Nothing
It now has failure awareness for free, with no effort by the original function author. Haskell has an infix synonym for fmap, <$>, that makes this even more natural:
unwords . reverse . words <$> Just "The quick brown fox" => Just "fox brown quick The"
This looks very much like the first example:
unwords . reverse . words $ "The quick brown fox" => "fox brown quick The"
This is really powerful because it means any function with no special context can now be used with any context that implements Functor (or Applicative for multi-argument functions). The view that fmap executes functions with no context in a special context also explains why fmap for lists is map. A function returning a list can be looked at as a function non-deterministically returning multiple values. This can be seen when using monadic bind (flatMap/concatMap) with functions returning lists:
[1..5] >>= (\x -> [x-1, x, x+1]) => [0,1,2,1,2,3,2,3,4,3,4,5,4,5,6]
Looking at lists like this, a function with only one return value is deterministic, so if it is given a non-deterministic value, the result should be the result of applying the deterministic function to each possible non-deterministic value with no change in the number of possible non-deterministic values, that is to say that it should be mapped over the list!
show $ 1 => "1"
show <$> [1..5] => ["1","2","3","4","5"]
fmap show [1..5] =>["1","2","3","4","5"]
The key idea here is that lifting like this provides a way to easily and extensibly compose functions with different expectations about the context in which they will be executing. This idea could be fruitfully applied in many languages outside of Haskell and I'm excited to see how it interacts with other parts of C++.