
On Thu, Nov 19, 2015 at 4:57 PM, Johannes Waldmann
Now, I don't want to bring on another general discussion of AMP -
That’s a curious way to frame your e-mail if this indeed is not your intent, but alright.
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.
I have almost always taught monads as if Applicative was a superclass of Monad. The strategy with which I’ve had most success is to begin describing functors as a general notion of typed computational contexts that are polymorphic in the type of the value produced by the computation, and that may have effects in the context of the computation that go beyond merely computing a value. The word «effect» is sadly suggestive of IO, and perhaps using terms like «semantic domain» instead of «computational context» and «effect» may be more universal, but it turns out to be effective. I avoid using IO as an example of a functor until the very end of the lessons on the topic of monads in an attempt to counter that unfortunate suggestion of imperative interpretation; I also avoid mentioning «return» until the very end. After explaining Functors with examples on Identity, Maybe, Either, Reader and lists, we move on to the notion of an Applicative with the same examples, and finally the notion of a Monad with the same examples. The three classes are distinguished by their expanding APIs, and it’s helpful, if you have enough time for the lesson, to show types that are Functor but not Applicative (e.g. «(,) e»). I haven’t found a helpful example of an Applicative that is not a Monad that is practical for a lesson. After that, I present interesting terms to specify complex computation using «fmap», «<$>», «<*>», «pure» and «>>=»/«=<<», and finally, I introduce do notation as a nice way of writing chained monadic computations, usually with examples based on «Data.Map.lookup». Finally, I mention «return» exists as an alias of «pure» (even though it really is part of the class — I wish that it wasn’t and it’s hard to explain why it’s even there in the first place) and caution against using it as the imperative pun may mislead their intuition (my Haskell students are in their third year of the CS program, and they’ve done a lot of imperative programming by then). We usually cover IO in a later, separate session. A couple other times we’ve tried doing IO first and the Functor/Applicative/Monad hierarchy later, but students seemed to end up more confused with that strategy (anecdotically, of course).
(The intersection of AMPers and teachers is non-empty?)
I used to have to explain the superclass should have been there but wasn’t for historical reasons, and that led to some time being wasted, and some extra, unnecessary confusion. That’s fixed now, and that particularly difficult lesson is now a bit less confusing. I’m very happy that this was finally fixed, and not having to explain that awful old situation frees up some time so I can present more examples of monad instances and monadic computations, and explain them in greater depth.