On Fri, Nov 20, 2015 at 4:31 AM, Erik Hesselink <hesselink@gmail.com> wrote:
On 20 November 2015 at 02:30, Manuel Gómez <targen@gmail.com> wrote:
> I haven’t found a helpful example of an Applicative that is not a Monad
> that is practical for a lesson.

There's ZipList [0], which depending on the type of audience might be
doable. There's also Const [1], but that needs a Monoid constraint,
and since you said you considered ((,) e) as not having an
Applicative, which it does have with a Monoid constraint, perhaps
Const isn't suitable to you for that reason. There are more
interesting examples here [2].

An easy way to find applicative functors that are not monads is through composition. Composing two applicative functors gives a kind of two-stage computation, where the outer functor can affect the inner one, but can’t depend on anything in the inner functor.

So, Compose (State s) Maybe a = s -> (Maybe a, s) will use state to create a partial value, but whether the final value is Nothing cannot affect the stateful part of the computation. So definitelyFail <*> modifyState will modify the state, even though an earlier part of the computation failed.

In contrast, MaybeT (State s) a = s -> (Maybe a, s) allows communication between the stages, so returning Nothing will abort the rest of the computation. I.e, definitelyFail <*> modifyState will not modify the state.

If that’s too confusing for students, an example like IO (Parser a) may be better. This cleanly separates the creation of the parser from its execution, but giving it a monad instance would require giving the IO stage access to the parser’s input and output.

--