AMP - how do you motivate this in teaching?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

AMP - how do you motivate this in teaching?

Johannes Waldmann-2
Because of AMP, I have to rewrite slides and example code
for my lectures, and I don't like it.

In fact I probably won't do it, and will advise students
to return to ghc-7.8 - but then, how does that look?


Really, my answer to

  [1] 3.5 Beginner friendliness
  How often did you say ... "A Monad is always an Applicative"

is: never. (for "is a Functor" - often. In fact, always)


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?)


- Johannes


[1] https://wiki.haskell.org/Functor-Applicative-Monad_Proposal

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: AMP - how do you motivate this in teaching?

Tony Morris
I have had to work around AMP not existing since 2006 in teaching. Thank goodness it is finally here and my students are no longer confused.

That's how.

On Fri, Nov 20, 2015 at 7:27 AM, Johannes Waldmann <[hidden email]> wrote:
Because of AMP, I have to rewrite slides and example code
for my lectures, and I don't like it.

In fact I probably won't do it, and will advise students
to return to ghc-7.8 - but then, how does that look?


Really, my answer to

  [1] 3.5 Beginner friendliness
  How often did you say ... "A Monad is always an Applicative"

is: never. (for "is a Functor" - often. In fact, always)


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?)


- Johannes


[1] https://wiki.haskell.org/Functor-Applicative-Monad_Proposal

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: AMP - how do you motivate this in teaching?

Manuel Gómez
In reply to this post by Johannes Waldmann-2
On Thu, Nov 19, 2015 at 4:57 PM, Johannes Waldmann
<[hidden email]> wrote:
> 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.
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: AMP - how do you motivate this in teaching?

Joachim Breitner-2
Hi,

thanks for your mail! I am circulating it to my Haskell teaching
colleagues, who are facing the same challenges as Johannes.

Am Donnerstag, den 19.11.2015, 21:00 -0430 schrieb Manuel Gómez:
> 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»).

There is the instance
    Monoid a => Applicative ((,) a)
Do you touch upon that, or pretend it is not there?

Greetings,
Joachim

--
Joachim “nomeata” Breitner
  [hidden email]http://www.joachim-breitner.de/
  Jabber: [hidden email]  • GPG-Key: 0xF0FBF51F
  Debian Developer: [hidden email]


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: AMP - how do you motivate this in teaching?

Martin Heuschober
I just recently had a presentation at my local usergroup (Lambdaheads/Vienna) where I introduced the problem of `null` values and the functional solution of using functor, applicative and monad to solve this.

The slides are available - https://github.com/epsilonhalbe/Talks/tree/master/20151021-LH-Func - if you have comments on them, I'd be glad to hear, during the meetup we had quite a discussion about it, but in the end I think everyone agreed that those abstractions are handy and quite natural in their origination.

the tldr of it is:
that in functional languages, one major point of doing things is function composition and to introduce new functions (in this case operators) to solve the problem when domains do not match properly, i.e. to put the complicated part in the composition and not bother the programmer with it.

I think the "excuse" for `return` existing is historical which I think is no bad thing to say when teaching, because it makes students aware that everything is being improved over time and that they might be the ones helping.

Cheers Martin

2015-11-20 9:22 GMT+01:00 Joachim Breitner <[hidden email]>:
Hi,

thanks for your mail! I am circulating it to my Haskell teaching
colleagues, who are facing the same challenges as Johannes.

Am Donnerstag, den 19.11.2015, 21:00 -0430 schrieb Manuel Gómez:
> 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»).

There is the instance
    Monoid a => Applicative ((,) a)
Do you touch upon that, or pretend it is not there?

Greetings,
Joachim

--
Joachim “nomeata” Breitner
  [hidden email]http://www.joachim-breitner.de/
  Jabber: [hidden email]  • GPG-Key: 0xF0FBF51F
  Debian Developer: [hidden email]


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe



_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: AMP - how do you motivate this in teaching?

Erik Hesselink
In reply to this post by Manuel Gómez
On 20 November 2015 at 02:30, Manuel Gómez <[hidden email]> 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].

Erik

[0] https://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Applicative.html#t:ZipList
[1] http://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Applicative.html#v:Const
[2] http://stackoverflow.com/questions/7220436/good-examples-of-not-a-functor-functor-applicative-monad
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: AMP - how do you motivate this in teaching?

Oleg Grenrus

On 20 Nov 2015, at 11:31, Erik Hesselink <[hidden email]> wrote:

On 20 November 2015 at 02:30, Manuel Gómez <[hidden email]> 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].


There are also (which I find actually useful):

-  `Concurrently = Concurrently (IO a)` which is Monad only IO effects are commutative. [3]
    - one can argue that Applicative and Monad instances aren’t compatible
- `Errors` [4], which could be specialised to `Either (NonEmpty err) a` and `ap` would gather all errors!
    - and of course `Lift` using which `Errors` is defined.


- Oleg

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

signature.asc (859 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: AMP - how do you motivate this in teaching?

Joachim Breitner-2
Hi,

Am Freitag, den 20.11.2015, 12:02 +0200 schrieb Oleg Grenrus:
> - `Errors` [4], which could be specialised to `Either (NonEmpty err)
> a` and `ap` would gather all errors!

this is actually a pretty nice and convincing example: „A effectful
computation (e.g. a stateless parser) that may fail in various spots
with errors, where the type system can guarantee that _all_ errors will
be reported (and not just the first found).“ 

Obviously a Monad cannot provide this guarantee, and obviously, there
are applications where this is impossible, so this nicely shows the
usefulness of Applicative as a separate abstraction.

Greetings,
Joachim

--
Joachim “nomeata” Breitner
  [hidden email]http://www.joachim-breitner.de/
  Jabber: [hidden email]  • GPG-Key: 0xF0FBF51F
  Debian Developer: [hidden email]


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: AMP - how do you motivate this in teaching?

Tony Morris-4
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256



On 20/11/15 20:15, Joachim Breitner wrote:

> Hi,
>
> Am Freitag, den 20.11.2015, 12:02 +0200 schrieb Oleg Grenrus:
>> - `Errors` [4], which could be specialised to `Either (NonEmpty
>> err) a` and `ap` would gather all errors!
>
> this is actually a pretty nice and convincing example: „A
> effectful computation (e.g. a stateless parser) that may fail in
> various spots with errors, where the type system can guarantee that
> _all_ errors will be reported (and not just the first found).“
>

It's a pretty nice example of further splitting of the type-class
hierarchy, since if given,

instance Monoid a => Applicative (Either a) where
  -- we gather all the errors

then we could not have Either (NonEmpty err), since (NonEmpty err)
does not have a Monoid, only a binary, associative operation (Semigroup)
.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQEcBAEBCAAGBQJWTw/vAAoJEFkczQCvdvv0T4cH/28/pj2xqaRDHAGtoLF5mnLA
phbQ9J3mbbdmTQLlx5Rp77VCBV2BvjLe4gu+sCz+Qb/cvXo9lsCpJUCZFMP6CMSF
HMLD6hxZqCTyKu0/47Lmrh6AvkWFQ/YG2N99ZK4el3omoRXsBbGTxwOUBAPm5jZZ
94X6Q5jFoHOqCmeL1I7GTyx4IhnzOeMb2vTJvaiDbNUelu34ZzyzPLpaLA5uxnoC
G3MZNUeHX3USPzhg2KOwno6NNmHO8E8p90TiUWriLCjr8x6VqYj+5tNx6IVamA61
0nIE2BQo/D6n8Zr+LxWmVKoaC1QK/K5wGONmIcZRDCl6IW1aGD4XkuHcWGhnQqg=
=A8/9
-----END PGP SIGNATURE-----
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: AMP - how do you motivate this in teaching?

Joachim Breitner-2
Hi,

Am Freitag, den 20.11.2015, 22:20 +1000 schrieb Tony Morris:
> It's a pretty nice example of further splitting of the type-class
> hierarchy, since if given,
>
> instance Monoid a => Applicative (Either a) where
>   -- we gather all the errors
>
> then we could not have Either (NonEmpty err), since (NonEmpty err)
> does not have a Monoid, only a binary, associative operation
> (Semigroup)

I believe that there are plans to move Semigroup into Base. Eventually,
there will be a transition to Monoid having Semigroup as a superclass¹,
and I guess then the instance can be changed to 
    instance Monoid a => Applicative (Either a) where
and that worry is gone.

Greetings,
Joachim

¹ https://ghc.haskell.org/trac/ghc/ticket/10365 and
  https://ghc.haskell.org/trac/ghc/wiki/Proposal/SemigroupMonoid


--
Joachim “nomeata” Breitner
  [hidden email]http://www.joachim-breitner.de/
  Jabber: [hidden email]  • GPG-Key: 0xF0FBF51F
  Debian Developer: [hidden email]


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: AMP - how do you motivate this in teaching?

M Farkas-Dyck
In reply to this post by Manuel Gómez
On 19/11/2015, Manuel Gómez <[hidden email]> wrote:
> I haven’t found a helpful example of an Applicative that is not a Monad
> that is practical for a lesson.

I like this one: https://hackage.haskell.org/package/regex-applicative
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: AMP - how do you motivate this in teaching?

Christopher Allen
I'm partial to hackage.haskell.org/package/validation myself :)

On Fri, Nov 20, 2015 at 9:51 AM, M Farkas-Dyck <[hidden email]> wrote:
On 19/11/2015, Manuel Gómez <[hidden email]> wrote:
> I haven’t found a helpful example of an Applicative that is not a Monad
> that is practical for a lesson.

I like this one: https://hackage.haskell.org/package/regex-applicative
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe



--
Chris Allen
Currently working on http://haskellbook.com

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: AMP - how do you motivate this in teaching?

David Menendez-2
In reply to this post by Erik Hesselink
On Fri, Nov 20, 2015 at 4:31 AM, Erik Hesselink <[hidden email]> wrote:
On 20 November 2015 at 02:30, Manuel Gómez <[hidden email]> 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.

--

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: AMP - how do you motivate this in teaching?

Albert Y. C. Lai
In reply to this post by Johannes Waldmann-2
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.
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe