
On 2015-11-19 04:27 PM, Johannes Waldmann wrote:
Now, I don't want to bring on another general discussion of AMP - instead I'd like to hear from people who use monads in teaching (e.g., to define semantic domains) about how they sell "Applicative m =>" to their students. (The intersection of AMPers and teachers is non-empty?)
(I do not teach Haskell. But I teach other things, and I explain Haskell things in local Haskell meetups.) I'm pretty sure we can all agree to start with Functor. This gives us fmap so we can apply a 1-ary function to 1 action. But we are greedy, we also want to apply a 2-ary function to 2 actions. Functor alone can't do this. We need at least liftA2. And then we wonder about 3-ary, 4-ary... It turns out that pure and (<*>) cover them all. To apply a 5-ary function to 5 actions, we can write the very regular pure f <*> as <*> bs <*> cs <*> ds <*> es (Given lambda calculus and Functor, the following suites have equivalent ability, so each suite could define Applicative: {pure, liftA2}, {pure, liftA2 (,)}, {pure, (<*>)}.) It also turns out that you can already write sequenceA (you didn't use all of Monad to get sequence) and traverse (you didn't use all of Monad to get mapM). So this is how I would motivate Applicative given Functor. I received the gift of 1-ary application, but then I get greedy and want n-ary application and the silver axe and the golden axe... The final transition, from Applicative to Monad, is driven by a whole new level of greed. I received the gift of n-ary application and a silver axe and a golden axe; now I want a smart axe. Here is what I mean: In the compound action fs <*> xs the sub-action fs cannot behave dependently on what "return value" the sub-action xs "returns". (Likewise for the other way round.) That data dependency is provided by Monad's (>>=) or (=<<). One operand can now peak at the "return value" of the other sub-action, and do some Turing-smart processing, before it decides what action to take. This is my version of what other people call successively expanding API.