Proposal: Applicative => Monad: Call for consensus

Maciej Piechotka uzytkownik2 at gmail.com
Mon Jan 10 04:41:57 CET 2011


On Sun, 2011-01-09 at 18:16 -0800, Iavor Diatchki wrote:
> Hello,
> In my experience, defining monads in terms of "fmap" and "join" leads
> to code duplication.  The examples we have seen in this thread---so
> far---are a bit misleading because they compare a partial
> implementation of a monad (join without fmap) with a complete
> implementation (bind).  Here is an example of what I mean:
> 
> 
> data SP a               = PutChar Char (SP a)
>                         | GetChar (Char -> SP a)
>                         | Return a
> 
> 
> fmapSP :: (a -> b) -> (SP a -> SP b)
> fmapSP f (PutChar c sp) = PutChar c (fmapSP f sp)
> fmapSP f (GetChar k)    = GetChar (\c -> fmapSP f (k c))
> fmapSP f (Return a)     = Return (f a)
> 
> 
> joinSP :: SP (SP a) -> SP a
> joinSP (PutChar c sp)   = PutChar c (joinSP sp)
> joinSP (GetChar k)      = GetChar (\c -> joinSP (k c))
> joinSP (Return sp)      = sp
> 
> 
> bindSP :: (a -> SP b) -> (SP a -> SP b)
> bindSP f (PutChar c sp) = PutChar c (bindSP f sp)
> bindSP f (GetChar k)    = GetChar (\c -> bindSP f (k c))
> bindSP f (Return a)     = f a
> 
> 
> I chose this example because I think that it illustrates nicely how
> the three operators work, I hope that other readers find it useful.
> 

Yes and no:

1. In monad transformers & co. you want weakened conditions on Functor
and Applicative so you cannot reuse (>>=) in them - you end up with a
function anyway.

2. I don't recall anyone claiming it is shorter - the only claim was
that it was simpler to think of (for some people) and 'nicer' from
mathematical standpoint. Simplifying problem is common technique so I
guess that defence of join is unharmed.

Say - you want to prove linearity of function φ - you can either:
 1. Prove aφ(x) = φ(ax) and φ(x) ⊕ φ(y) = φ(x + y)
 2. Prove aφ(x) ⊕ bφ(y) = φ(ax + by)

Which one do you choose? well it depends on φ and your skills. If φ is
simple you and you have done it before you may prefer the 2. Otherwise
you may prefer 1 even if it longer.

> 
> 2011/1/9 Conal Elliott <conal at conal.net>
>         * The familiarity advantage of (>>=) is a historical accident.
>         I like to see the language improve over time, rather than
>         accumulate accidents.
> 
> 
> I would be surprised if choosing ">>=" was an accident: it seems more
> likely that it was chosen because it matches a commonly occurring
> pattern in functional programs, and abstraction is all about giving
> names to common patterns. 

Yes and no. Common pattern is function of form (read :: Read a => String
-> a) - surprisingly it is not the one you define as it is too limited.

(>>=) is probably better described as 'what happens' and functional
programming is not about what happens but what people want to achieve
(usually (>>=) but not always) or what people find easier to think about
(quick survey of this thread point into direction of join).

PS. As of simplifying. I have a feeling that the thread is:

around 6 people with opinion (sorry if I've counted incorrectly):
 - Ok - sometimes (>>=) is simpler for implementation sometimes join so
adding join would allow to choose simpler one or favourite

1 person with opinion
 - But (>>=) is great and noone is using join so why bother with join

PPS. As of tutorials - somehow I don't recall anyone bothering with
getting in deep of Read class on my Haskell course. Tutorial may not
even mentioning it as class method and novice will not notice that the
method existed

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://www.haskell.org/pipermail/libraries/attachments/20110110/190ed34b/attachment.pgp>


More information about the Libraries mailing list