|
Boost : |
From: Brian McNamara (lorgon_at_[hidden])
Date: 2003-10-21 08:27:15
(Note: useful URL appears later in this message.)
On Tue, Oct 21, 2003 at 03:43:14AM -0500, David B. Held wrote:
> "Brian McNamara" <lorgon_at_[hidden]> wrote in message
> news:20031020184847.GA14264_at_lennon.cc.gatech.edu...
> > [...]
> > I'd be very interested to see how someone who doesn't know
> > monads goes about writing a generic C++ implementation of
> > mothersPaternalGrandfather", which works for all the cases
> > (Sheep have {exactly 1, 0 or 1, any number} of each type of
> > parent). That example, while contrived, captures much of the
> > essence of monads.
>
> template <typename SheepT>
> SheepT mother( SheepT s ) throw( NoSuchAncestor );
> template <typename SheepT>
> SheepT father( SheepT s ) throw( NoSuchAncestor );
>
> template <typename SheepT>
> SheepT mothersPaternalGrandfather( SheepT s )
> throw (NoSuchAncestor )
> {
> return father(father(mother(s)));
> }
>
> exactly 1: SheepT == Sheep
> 0 or 1: SheepT == variant<Sheep, noSheep>
> any number: SheepT == vector<Sheep>
>
> But the devil is in the details. I get the feeling that even
> though my solution effectively does the same thing as
> yours, that it misses the point of monads. The problem
Yep. I used three monads which are all concerned with "arities".
A better formulation of the contrived problem would include a version
that uses, e.g., the state monad. One such formulation: we keep track
of how many times mother() and father() each get called. But...
> may be that FP and IP are so different that the focus is
> placed differently, and thus implementations aren't really
> comparable. After all, the real work is done in the mother()
> and father() functions, and we have left those unspecified.
>
> Part of the problem is that this example is so contrived,
> I'm having a hard time linking it to something useful. Your
...yeah. A tiny contrived example doesn't do justice to monads.
Probably the best motivating examples I know of are in Wadler's
"Monads for functional programming", available at
http://www.research.avayalabs.com/user/wadler/topics/monads.html
It's a longish paper (~31 pages), but Wadler is an excellent (and often
entertaining) writer.
> What might help is to look at some real world use-cases,
> like the I/O monads mentioned in the tutorial. If we could,
> say compare some basic I/O monad with the analogous
> functionality in, say, iostreams, that might illustrate a
> practical benefit of monads that even a C++ coder can
> relate to. ;)
I don't think the IO monad is a good example. Haskell programmers must
use the IO monad out of necessity. We don't have that necessity in C++.
If we want to motivate monads in C++, it should be with examples where
structuring the program monadically creates a winning generic design.
(Monadic parser combinators are perhaps a good example, but they're also
a big example, and it'll be a while before I have anything to show in
this domain.)
-- -Brian McNamara (lorgon_at_[hidden])
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk