Closed tabatkins closed 7 years ago
Thanks for explaining. I can definitely use that to refine the definition.
On Mon, Jul 25, 2016, 11:42 AM Tab Atkins Jr. notifications@github.com wrote:
The definition of Lift is pretty incorrect. It states
Lift is like map except it can be applied to multiple functors.
but that has nothing to do with lift, that's a property of the functor being applicative. Given an applicative functor, you can apply a function over multiple functor arguments without lift: arg1.of(f).ap(arg1).ap(arg2). (It's definitely not pretty, which is one reason why lifting is so much better, but still.)
The definition is further wrong because it talks about the map-equivalent version of lift, which definitely doesn't have the property being discussed; it only makes the function handle plain functors, not applicative functors. You need the ap-equivalent version (in Haskell, liftA).
lift is just the name given to map/ap/chain when the arguments are reversed (function first, then data) and partially applied.
Here's a suggested rewrite:
"Lift" has a few meanings. Sometimes people will talking about "lifting a value" into a functor; this refers to calling the of function on the value.
When "lift" is referred to as a function, though, it's just a variation of map, ap, or chain that takes the function argument first, and returns a new function that takes the functor value and maps/aps/chains on it. That is, given the map-equivalent version of lift, arg.map(f) is identical to lift(f)(arg). Lifting the function, rather than using map directly, makes it easier to pass the function around and apply it to other values, as it lets you use normal function-call syntax, passing arguments, rather than having to specially use the map method.
This is more obvious when you're using an applicative functor, which allows a function to be called with multiple functor arguments. Using the ap function, you'd have to write [].of(f).ap(arg1).ap(arg2), while lifting lets you just write liftA(f)(arg1, arg2). (You do need to specify which version of lift you're using; traditionally this is done with lift for plain functors, liftA for applicative functors, and liftM for monadic functors.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/hemanth/functional-programming-jargon/issues/70, or mute the thread https://github.com/notifications/unsubscribe-auth/AAB-4MXlUpuCVDuMJlkmnSMcJcsOjeIgks5qZQN3gaJpZM4JUa9t .
Awesome, a PR would be really useful! @tabatkins
Thank you @jethrolarson! 👍
Been almost a year, so I think we can close.
The definition of Lift is pretty incorrect. It states
but that has nothing to do with
lift
, that's a property of the functor being applicative. Given an applicative functor, you can apply a function over multiple functor arguments withoutlift
:arg1.of(f).ap(arg1).ap(arg2)
. (It's definitely not pretty, which is one reason why lifting is so much better, but still.)The definition is further wrong because it talks about the
map
-equivalent version oflift
, which definitely doesn't have the property being discussed; it only makes the function handle plain functors, not applicative functors. You need theap
-equivalent version (in Haskell,liftA
).lift
is just the name given tomap
/ap
/chain
when the arguments are reversed (function first, then data) and partially applied.Here's a suggested rewrite:
"Lift" has a few meanings. Sometimes people will talking about "lifting a value" into a functor; this refers to calling the
of
function on the value.When "lift" is referred to as a function, though, it's just a variation of
map
,ap
, orchain
that takes the function argument first, and returns a new function that takes the functor value and maps/aps/chains on it. That is, given themap
-equivalent version oflift
,arg.map(f)
is identical tolift(f)(arg)
. Lifting the function, rather than usingmap
directly, makes it easier to pass the function around and apply it to other values, as it lets you use normal function-call syntax, passing arguments, rather than having to specially use themap
method.This is more obvious when you're using an applicative functor, which allows a function to be called with multiple functor arguments. Using the
ap
function, you'd have to write[].of(f).ap(arg1).ap(arg2)
, while lifting lets you just writeliftA(f)(arg1, arg2)
. (You do need to specify which version oflift
you're using; traditionally this is done withlift
for plain functors,liftA
for applicative functors, andliftM
for monadic functors.