3 ms·
It seems to me that people often overthink applicative. It falls right out of functor. Normally when you call fmap, you pass it a function that takes a single
by mikekchar 8y ago
It seems to me that people often overthink applicative. It falls right out of functor. Normally when you call fmap, you pass it a function that takes a single parameter. What happens if you pass it a function that takes more than one parameter (the other parameters being curried)? fmap applies a value from the functor to the function. Since it only passes one parameter, the result is a partially applied function. The result is that you end up with a functor containing partially applied functions.
For example, take a list of number and a function that takes 2 parameters, x and y. Maybe the function adds x to y (it doesn't matter). Pass these to fmap. Your result will be a list of partially applied functions with x being set to the values in the list. Now we want to apply the y parameter. We need something similar to fmap, but rather than taking a function and a functor, it needs to take a functor containing functions and a functor containing data. It will then apply the data to the functions and you will end up with a functor containing the result.
That's all applicative is. It applies the subsequent parameters to the result of having run fmap on functions that have more than one parameter. It shows up in a lot of different places, though and is incredibly handy. When I'm writing FP style code in languages that don't normally curry parameters, I often find myself currying parameters precisely because I want applicative ;-). It's just super convenient.
NB: pure being part of applicative is really interesting. I don't know for sure, but I'm relatively sure that a functor is applicative IFF your can define pure for it, which is really interesting to think about.
Edit: weird wording
- cosmic_quanta 8y agoThat's a great explanation. This is similar to the post's example with tree of functions <*> tree of values = tree of results.
- deleted 8y ago[deleted]
- lmm 8y ago> It seems to me that people often overthink applicative. It falls right out of functor. Normally when you call fmap, you pass it a function that takes a single parameter. What happens if you pass it a function that takes more than one parameter (the other parameters being curried)? fmap applies a value from the functor to the function. Since it only passes one parameter, the result is a partially applied function. The result is that you end up with a functor containing partially applied functions. I blame this on Haskell's overreliance on currying. If applicative was explained in terms of (pure and) liftA2 aka map2, which is completely equivalent to defining it in terms of ap, the analogy with Functor would be much more obvious. > NB: pure being part of applicative is really interesting. I don't know for sure, but I'm relatively sure that a functor is applicative IFF your can define pure for it, which is really interesting to think about. Not true. Const b (i.e. f a = b for all a) forms a valid functor and you can define pure as long as there's at least one value of type b (pure a = 1 where 1 is that value), but if b is some type that does not form a monoid (e.g. nonzero octonions) then Const b does not from an applicative.
- mikekchar 8y agoCheers! That's a great example.