Difference between revisions of "Meet Bob The Monadic Lover"

From HaskellWiki
Jump to navigation Jump to search
m
m (trying to make my english readeble... I didn't say understandable, did I?)
Line 4: Line 4:
   
   
This is what I have in mind: suppose we have a friend who does very
+
So, this is what I have in mind: suppose we have a friend who does very
well with females/males. A lot of dating and so on...
+
well with females/males. A lot of dating and so...
   
 
Now, we would like to keep track of all his/her ... ehm, affairs...
 
Now, we would like to keep track of all his/her ... ehm, affairs...
   
So let's create a type: we will call it Lover, and its constructor will
+
Let's create a type for that: we'll call it "Lover", and a "Lover" will be its constructor.
be Lover.
 
   
Here it is:
+
There it is:
 
<haskell>
 
<haskell>
   
Line 22: Line 21:
   
 
Very very simple: it is a type where we can store the name of our
 
Very very simple: it is a type where we can store the name of our
  +
friend's beloveds.
friend's beloved. Suppose our friend is a male. We will call him Bob.
 
   
 
Suppose our friend is a male. We will call him Bob.
Ok, now we start playing a bit. But first some useful functions:
 
  +
 
Ok, we now start playing a bit. But first some useful functions we are
  +
going to need:
   
 
<haskell>
 
<haskell>
   
 
> createLover name times = Lover (name,times)
 
> createLover name times = Lover (name,times)
> startAffair name (Lover (names,times)) = Lover (name,0)
+
> startAffairWith name (Lover (names,times)) = Lover (name,0)
   
 
</haskell>
 
</haskell>
Line 37: Line 39:
   
 
Very simple: createLover takes a name of a beloved and the number of
 
Very simple: createLover takes a name of a beloved and the number of
... dates.
+
... let's call them "dates".
   
The other function, startAffair, takes the beloved's name and a lover.
+
The other function, startAffairWith, takes the beloved's name and a
The will then substitute the lover's past beloved names with the new
+
lover. It will then substitute the lover's past beloved names with the
beloved's one and remove every track of Bob's previous activities.
+
new beloved's one and remove every track of Bob's previous activities.
   
Yes, you can say it: she's very jealous of your past, as you can
+
Yes, you can say that: she's a very jealous tupe of chick and hates
  +
Bob's past, as you can imagine... Let's face it, Bob is not a saint,
imagine...
 
  +
after all.
   
You can visualize startAffair as the name of the person you are
+
If you want you can visualize "startAffairWith" with the name of the
starting a relationship with:
+
person you are starting a relationship with:
   
 
<haskell>
 
<haskell>
   
> jenny = startAffair "Jenny "
+
> jenny = startAffairWith "Jenny "
> luisa = startAffair "Luisa "
+
> luisa = startAffairWith "Luisa "
> antonia = startAffair "Antonia "
+
> antonia = startAffairWith "Antonia "
   
 
</haskell>
 
</haskell>
   
Well, jenny, luisa and antonia are partial applications. They need a lover!
+
As you may see, jenny, luisa and antonia are just partial
  +
applications. They need a lover! Well, we know this kind of types,
  +
don't we?
  +
  +
Be honest. With yourself, at least!
  +
  +
Now we need to create our lover. So, let's do it the right way.
   
So now need to create our lover, Bob:
+
I'd like to introduce you my friend Bob:
   
 
<haskell>
 
<haskell>
Line 82: Line 91:
   
 
Obviously when you start an affair you do not just meet once, without
 
Obviously when you start an affair you do not just meet once, without
doing anything... I mean, Bob is proud of his past record and would
+
doing anything... Well, perhaps the first date you just be quit, but
  +
in the end...
like to see the 5 increased!
 
   
  +
What I mean is that Bob is quite proud of his past record and would
Instead everytime he starts a new affair he has to pretend, with his
 
 
like to see the 5 increased! I can understand him.
lover, this is the first time!
 
   
 
Instead everytime he starts a new affair with those "always looking
Not what he wants really.
 
  +
for a lover" chicks, well, he has to pretend it is his first time!
   
 
Not what he wants, really.
Quite human, I'd say.
 
   
 
Quite human, I'd say. Still, he has to.
Let's give Bob a method to ... well, you know...
 
  +
 
Why don't we just give Bob a new method to ... well, you know...
   
 
<haskell>
 
<haskell>
Line 100: Line 112:
 
</haskell>
 
</haskell>
   
oneMoreTime does what it says: add one more time in Bob's personal record.
+
oneMoreTime does what it says, and doues it well: adds one more time in
  +
Bob's personal diary.
   
Let's try it:
+
Let's see:
   
 
*Main> oneMoreTime bob
 
*Main> oneMoreTime bob
Line 116: Line 129:
 
the "Real Love", if you know what I mean.
 
the "Real Love", if you know what I mean.
   
He needs one more method:
+
Indeed he needs one more method:
   
 
<haskell>
 
<haskell>
Line 125: Line 138:
   
 
changeBeloved is very simple: takes a name of a new beloved and
 
changeBeloved is very simple: takes a name of a new beloved and
concatenate with the names stored in Bob's loverDiary. Bob is proud
+
concatenate it with the names stored in Bob's loverDiary. Bob is proud
of his record, and does not pretend to be a fresh men every time he
+
of his diary, and does not pretend to be a freshman every time he
starts a new reletionship.
+
starts a new relationship.
   
What kind of a type is this Bob!
+
What kind of a type this Bob is!
   
Let's test how our Bob is doing. Remember that he started with Paula and 5 times in his record:
+
Let's test how our Bob is doing. Remember that he started with Paula
  +
and 5 times in his record, that is not a bad start compared to mine:
   
 
*Main> oneMoreTime $ oneMoreTime (luisa bob)
 
*Main> oneMoreTime $ oneMoreTime (luisa bob)
Line 143: Line 157:
 
*Main>
 
*Main>
   
He's doing quite fine, I'd say, if you like this kind of types.
+
Bob's doing quite fine, I'd say, if you like this kind of types.
   
New you can see the different behaviors: (antonia bob) will make Bob
+
Now you can alse see Bob's different approaching techniques: "(antonia
forget about Paula, while (changeBeloved "Carla " bob) will not.
+
bob)" will make Bob forget about Paula, while "(changeBeloved "Carla "
  +
bob)" will not.
   
I'm sure you know what method Bob likes most. And if I were to be Bob,
+
I'm sure you know what method Bob likes most.
well, I would agree with him, I must confess.
 
   
  +
Bob is that kind of types who just likes to increase the number of
So we need a new method, for those kind of types like Bob. This
 
  +
"pieces" in their collection. Their lovers, indeed, are just "pieces".
  +
 
I mena, if I were to be Bob, well, I would agree with him, I must
  +
confess. Luckily I'm not Bob and my beloved seems to appreciate this
  +
fact, especially when Bob comes over with a couple of those stupid
  +
gorgeous looking chicks. She keeps keeping an eye on me. She doesn't
  +
trust me and probably thinks that inside myself there must be some
  +
kind of a type like the type of Bob.
  +
  +
Sometimes I even start to believe that she could be right... But now
  +
we are talking about Bob, a much more interesting chap the me.
  +
 
Anyway we need a new method, for those kind of types like Bob. This
 
methods has to chain affairs without letting those ladies erase our
 
methods has to chain affairs without letting those ladies erase our
memory! It's just a matter of "male's determination"!
+
memory! It's just a matter of "lover's self-determination"!
   
I hate writing this thing, but... let's face reality!
+
I hate writing these things, but... let's face reality!
   
 
So, there's the (typically masculine) method:
 
So, there's the (typically masculine) method:
Line 168: Line 195:
 
together: the new lady (++) with the old ones, and newtimes + oldtimes!
 
together: the new lady (++) with the old ones, and newtimes + oldtimes!
   
That's all what Bob wants! And needs!
+
That's all Bob wants! And needs!
   
 
Let's see if it works:
 
Let's see if it works:
Line 182: Line 209:
   
 
Now, this is fine, sure. It fits Bob's needs. Still we would like to
 
Now, this is fine, sure. It fits Bob's needs. Still we would like to
have some way of stating how many times an affairs resulted in a ...
+
have some way of counting how many times an affairs resulted in a ...
well, we know what we mean.
+
well, I'm sure you know what I mean.
   
I'd like to take a quite general solution, because Bob is lazy and
+
I'd like to take a quite general solution here, because our Bob is quite a lazy guy and
sometimes forgets to update his diary. So we would like to be able to
+
sometimes, often,he forgets to update his diary, especially those nights he drunk too much. He is not an heavy drinker, far from it, but sometimes...
  +
write that the number of... times doubled:
+
So we would like to be able to write that the number of times ...
  +
doubled. Hard to believe, but you never know with types like Bob:
   
 
<haskell>
 
<haskell>
Line 201: Line 230:
 
*Main>
 
*Main>
   
So: Bob started at 5 with Paula, doubled it change Paula for Carla.
+
So: Bob started at 5 with Paula, doubled it when changed Paula for
  +
Carla (let me tell you: a good change!). Then he met Antonia, (the
Then met Antonia, (the real love?) and told her he never did anything
+
real love?) and told her he never did anything bad in his past (I was
bad. We Antonia he did it 3 times.
 
  +
there and could not refrain from laughing). With Antonia he did it 3
  +
times. Or so he pretends. But I know Antonia and this is probably
  +
true. Anyway, never trust what Bob says, ever!
   
 
Remember: when an affair is started by a beloved, like "(antonia bob)",
 
Remember: when an affair is started by a beloved, like "(antonia bob)",
we can only use "+", since antonia pretends Bob to be a freshman!
+
we can only use "+", since Antonia pretends Bob to be a freshman!
   
 
*Main> chainAffairs (times (+3) (antonia bob)) (times (*2) (luisa bob))
 
*Main> chainAffairs (times (+3) (antonia bob)) (times (*2) (luisa bob))
Line 218: Line 250:
 
*Main>
 
*Main>
   
I'll ask it again: what kind of a type is this Bob!!! A sex
+
I'll ask it again: what kind of a type is this Bob??? A sex-intercourses calculating machine!
intercourses calculating machine!
 
   
 
There's a name for males who just collect ... well ... females: we
 
There's a name for males who just collect ... well ... females: we
 
call them Macho Men!
 
call them Macho Men!
   
Like Bob they just chain love affairs, doing just calculations:
+
Like Bob they just chain love affairs, doing just pure calculations:
   
 
<haskell>
 
<haskell>
Line 239: Line 270:
   
 
> instance Macho Lover where
 
> instance Macho Lover where
> chain (Lover (a,b)) (Lover (c,d)) = (Lover ((a++c),(b+d)))
+
> chain mychicks = chainAffairs mychicks
   
 
</haskell>
 
</haskell>
   
Do you really want some evidences??
+
Do you really need some evidences??
   
 
There you are:
 
There you are:
Line 251: Line 282:
 
*Main>
 
*Main>
   
Look at the way Bob performs his calculation. It is basically mapping
+
Look at the way Bob performs his calculations. He is basically mapping
its diary with some function. And indeed this is what "times" does.
+
his diary with some function. And indeed this is what "times" is
  +
supposed to do.
   
 
"times" is just a "map" for Bob's loverDiary.
 
"times" is just a "map" for Bob's loverDiary.
   
In Haskell there is a class for this kind of types. I mean, those types
+
In Haskell we have a class for this kind of types. I mean, those types
that can be mapped as Bob's loverDiary can.
+
who map objects that can be mapped over as Bob's loverDiary can.
   
  +
I think the name of their class i quite appropriate: they are called
They are called Functors. Pure calculating machine, without any soul left.
+
Functors. Pure calculating machine, without any soul left.
   
Sure Bob is an instance of this class, you can be sure:
+
Bob must be an instance of this class, you can be sure of that:
   
 
<haskell>
 
<haskell>
Line 294: Line 327:
   
 
</haskell>
 
</haskell>
  +
   
 
*Main> askLover (tellMyself 10) (tellLover 1)
 
*Main> askLover (tellMyself 10) (tellLover 1)
Line 303: Line 337:
 
*Main> askLover bob (tellLover 10)
 
*Main> askLover bob (tellLover 10)
 
Lover {loverDiary = ("Paula ",15)}
 
Lover {loverDiary = ("Paula ",15)}
  +
*Main>
  +
  +
bob last night
  +
*Main> fmap (*3) chain bob (askLover (changeBeloved "Jennyfer L. " (changeBeloved "Berta " (changeBeloved "Claudia" (antonia bob)))) (tellLover 10))
  +
Lover {loverDiary = ("Paula Antonia ClaudiaBerta Jennyfer L. ",45)}
  +
*Main>
  +
*Main> fmap (*3) $ askLover (changeBeloved "Jennyfer L. " (changeBeloved "Berta " (changeBeloved "Claudia" (antonia bob)))) (tellLover 10)
  +
Lover {loverDiary = ("Antonia ClaudiaBerta Jennyfer L. ",30)}
  +
*Main>
  +
*Main> chain bob $ fmap (*5) (askLover (changeBeloved "Jennyfer L. " (changeBeloved "Berta " (changeBeloved "Claudia" (antonia bob)))) (tellLover 10))
  +
Lover {loverDiary = ("Paula Antonia ClaudiaBerta Jennyfer L. ",55)}
 
*Main>
 
*Main>
   
Line 311: Line 356:
 
> m >>= f = askLover m f
 
> m >>= f = askLover m f
   
> whoLoved a = do newLove "Lorenza "
+
> whoLovedBy bob = do newLove "Lorenza "
> lorenza <- tellMyself 3
+
> lorenza <- tellMyself 3
> newLove "Antony "
+
> newLove "Antony "
> antony <- tellMyself 6
+
> antony <- tellMyself 6
> newLove "Luise "
+
> newLove "Luise "
> luise <- tellMyself 2
+
> luise <- tellMyself 2
> tellMyself (lorenza + antony + luise)
+
> tellMyself (lorenza + antony + luise)
   
 
</haskell>
 
</haskell>
   
*Main> whoLoved bob
+
*Main> whoLovedBy bob
 
Lover {loverDiary = ("Lorenza Antony Luise ",11)}
 
Lover {loverDiary = ("Lorenza Antony Luise ",11)}
 
*Main>
 
*Main>

Revision as of 06:53, 3 September 2006

Meet Bob The Monadic Lover

Note: The source of this page can be used as a Literate Haskel file and can be run with ghci or hugs: so cut paste change and run (in emacs for instance) while reading it...


So, this is what I have in mind: suppose we have a friend who does very well with females/males. A lot of dating and so...

Now, we would like to keep track of all his/her ... ehm, affairs...

Let's create a type for that: we'll call it "Lover", and a "Lover" will be its constructor.

There it is:

> newtype Lover a = Lover { loverDiary :: (Name,a) }
>     deriving (Show)
> type Name = String

Very very simple: it is a type where we can store the name of our friend's beloveds.

Suppose our friend is a male. We will call him Bob.

Ok, we now start playing a bit. But first some useful functions we are going to need:

 

> createLover name times = Lover (name,times)
> startAffairWith name (Lover (names,times)) = Lover (name,0)

Indeed we need a way to create a lover, Bob, and start an affair with some beloved.

Very simple: createLover takes a name of a beloved and the number of ... let's call them "dates".

The other function, startAffairWith, takes the beloved's name and a lover. It will then substitute the lover's past beloved names with the new beloved's one and remove every track of Bob's previous activities.

Yes, you can say that: she's a very jealous tupe of chick and hates Bob's past, as you can imagine... Let's face it, Bob is not a saint, after all.

If you want you can visualize "startAffairWith" with the name of the person you are starting a relationship with:

> jenny = startAffairWith "Jenny "
> luisa = startAffairWith "Luisa "
> antonia = startAffairWith "Antonia "

As you may see, jenny, luisa and antonia are just partial applications. They need a lover! Well, we know this kind of types, don't we?

Be honest. With yourself, at least!

Now we need to create our lover. So, let's do it the right way.

I'd like to introduce you my friend Bob:

> bob = createLover "Paula " 5

Bob had a previous beloved: Paula. They dated 5 times...

Easy, isn't it?

So let's start playing around:

 *Main> bob
 Lover {loverDiary = ("Paula ",5)}
 *Main> luisa bob
 Lover {loverDiary = ("Luisa ",0)}
 *Main> antonia bob
 Lover {loverDiary = ("Antonia ",0)}
 *Main> 

Obviously when you start an affair you do not just meet once, without doing anything... Well, perhaps the first date you just be quit, but in the end...

What I mean is that Bob is quite proud of his past record and would like to see the 5 increased! I can understand him.

Instead everytime he starts a new affair with those "always looking for a lover" chicks, well, he has to pretend it is his first time!

Not what he wants, really.

Quite human, I'd say. Still, he has to.

Why don't we just give Bob a new method to ... well, you know...

> oneMoreTime (Lover (name,times)) = Lover (name,times + 1)

oneMoreTime does what it says, and doues it well: adds one more time in Bob's personal diary.

Let's see:

 *Main> oneMoreTime bob
 Lover {loverDiary = ("Paula ",6)}
 *Main> oneMoreTime (antonia bob)
 Lover {loverDiary = ("Antonia ",1)}
 *Main> 


Fine, it works as expected.

Now, Bob is, well, that kind of type that seems not really believe in the "Real Love", if you know what I mean.

Indeed he needs one more method:

> changeBeloved newname (Lover (name,times)) = Lover (name ++ newname,times)

changeBeloved is very simple: takes a name of a new beloved and concatenate it with the names stored in Bob's loverDiary. Bob is proud of his diary, and does not pretend to be a freshman every time he starts a new relationship.

What kind of a type this Bob is!

Let's test how our Bob is doing. Remember that he started with Paula and 5 times in his record, that is not a bad start compared to mine:

 *Main> oneMoreTime $ oneMoreTime (luisa bob)
 Lover {loverDiary = ("Luisa ",2)}
 *Main> oneMoreTime $ oneMoreTime bob
 Lover {loverDiary = ("Paula ",2)}
 *Main> oneMoreTime $ oneMoreTime $ oneMoreTime $ oneMoreTime (antonia bob)
 Lover {loverDiary = ("Antonia ",4)}
 *Main> oneMoreTime $ oneMoreTime $ oneMoreTime $ changeBeloved "Carla " bob
 Lover {loverDiary = ("Paula Carla ",8)}
 *Main> 

Bob's doing quite fine, I'd say, if you like this kind of types.

Now you can alse see Bob's different approaching techniques: "(antonia bob)" will make Bob forget about Paula, while "(changeBeloved "Carla " bob)" will not.

I'm sure you know what method Bob likes most.

Bob is that kind of types who just likes to increase the number of "pieces" in their collection. Their lovers, indeed, are just "pieces".

I mena, if I were to be Bob, well, I would agree with him, I must confess. Luckily I'm not Bob and my beloved seems to appreciate this fact, especially when Bob comes over with a couple of those stupid gorgeous looking chicks. She keeps keeping an eye on me. She doesn't trust me and probably thinks that inside myself there must be some kind of a type like the type of Bob.

Sometimes I even start to believe that she could be right... But now we are talking about Bob, a much more interesting chap the me.

Anyway we need a new method, for those kind of types like Bob. This methods has to chain affairs without letting those ladies erase our memory! It's just a matter of "lover's self-determination"!

I hate writing these things, but... let's face reality!

So, there's the (typically masculine) method:

> chainAffairs (Lover (names,oldtimes)) (Lover (newlady,newtimes)) = Lover (newlady++names,newtimes+oldtimes)

This method is very simple: it takes two love affairs, the old one and the new one, and chains them together: the new lady (++) with the old ones, and newtimes + oldtimes!

That's all Bob wants! And needs!

Let's see if it works:

  *Main> chainAffairs (oneMoreTime $ oneMoreTime (antonia bob)) ( oneMoreTime $ changeBeloved "Carla " bob)
  Lover {loverDiary = ("Antonia Paula Carla ",8)}

Remember where Bob was starting from:

  *Main> bob
  Lover {loverDiary = ("Paula ",5)}
  *Main> 

Now, this is fine, sure. It fits Bob's needs. Still we would like to have some way of counting how many times an affairs resulted in a ... well, I'm sure you know what I mean.

I'd like to take a quite general solution here, because our Bob is quite a lazy guy and sometimes, often,he forgets to update his diary, especially those nights he drunk too much. He is not an heavy drinker, far from it, but sometimes...

So we would like to be able to write that the number of times ... doubled. Hard to believe, but you never know with types like Bob:

> times f (Lover (name,times)) = Lover (name, f times)

Let's see how this function works:

 *Main> chainAffairs (times (+3) (antonia bob)) (times (*2) $ changeBeloved "Carla " bob)
 Lover {loverDiary = ("Paula Carla Antonia ",13)}
 *Main> 

So: Bob started at 5 with Paula, doubled it when changed Paula for Carla (let me tell you: a good change!). Then he met Antonia, (the real love?) and told her he never did anything bad in his past (I was there and could not refrain from laughing). With Antonia he did it 3 times. Or so he pretends. But I know Antonia and this is probably true. Anyway, never trust what Bob says, ever!

Remember: when an affair is started by a beloved, like "(antonia bob)", we can only use "+", since Antonia pretends Bob to be a freshman!

  *Main> chainAffairs (times (+3) (antonia bob)) (times (*2) (luisa bob))
  Lover {loverDiary = ("Luisa Antonia ",3)}
  *Main> 

instead:

 *Main> chainAffairs (times (+3) (antonia bob)) (times (+2) (luisa bob))
 Lover {loverDiary = ("Luisa Antonia ",5)}
 *Main> 

I'll ask it again: what kind of a type is this Bob??? A sex-intercourses calculating machine!

There's a name for males who just collect ... well ... females: we call them Macho Men!

Like Bob they just chain love affairs, doing just pure calculations:

> class Macho f where
>     chain :: (Num a) => f a -> f a -> f a

It is plain obvious that a lover of the kind of Bob must be an instance of this class:

> instance Macho Lover where
>     chain mychicks = chainAffairs mychicks

Do you really need some evidences??

There you are:

 *Main> chain (times (+3) (antonia bob)) (chain (times (*2) (changeBeloved "Carla " bob)) (times (+2) (luisa bob)))
 Lover {loverDiary = ("Antonia Paula Carla Luisa ",15)}
 *Main> 

Look at the way Bob performs his calculations. He is basically mapping his diary with some function. And indeed this is what "times" is supposed to do.

"times" is just a "map" for Bob's loverDiary.

In Haskell we have a class for this kind of types. I mean, those types who map objects that can be mapped over as Bob's loverDiary can.

I think the name of their class i quite appropriate: they are called Functors. Pure calculating machine, without any soul left.

Bob must be an instance of this class, you can be sure of that:

> instance Functor Lover where
>     fmap f = times f

Do you still want some evidence?

  *Main> chain (fmap (+3) (antonia bob)) (chain (fmap (*2) (changeBeloved "Carla " bob)) (fmap (+2) (luisa bob)))
  Lover {loverDiary = ("Antonia Paula Carla Luisa ",15)}
  *Main> 


to be continued

Bob's conscience asking...

> askLover lover answer = Lover (oldnames ++ newname,newtimes)
>     where (oldnames,oldtimes) = loverDiary lover
>           (newname,newtimes) = loverDiary (answer oldtimes)

> tellLover newtimes oldtimes = Lover ("", newtimes+oldtimes)
> tellMyself newtimes = Lover ("", newtimes)
> newLove love = Lover (love,0)


 *Main> askLover (tellMyself 10) (tellLover 1)
 Lover {loverDiary = ("",11)} -- Leibniz
 *Main> askLover (newLove "Lory ") (tellLover 1)
 Lover {loverDiary = ("Lory ",1)}
 *Main> chain (bob) (chain (askLover (newLove "Cris ") (tellLover 2)) (askLover (antonia bob) (tellLover 4)))
 Lover {loverDiary = ("Paula Cris Antonia ",11)}
 *Main>  askLover bob (tellLover 10) 
 Lover {loverDiary = ("Paula ",15)}
 *Main> 

bob last night

 *Main> fmap (*3) chain bob  (askLover (changeBeloved "Jennyfer L. " (changeBeloved "Berta " (changeBeloved "Claudia" (antonia bob)))) (tellLover 10))
 Lover {loverDiary = ("Paula Antonia ClaudiaBerta Jennyfer L. ",45)}
 *Main> 
 *Main> fmap (*3) $ askLover (changeBeloved "Jennyfer L. " (changeBeloved "Berta " (changeBeloved "Claudia" (antonia bob)))) (tellLover 10)
 Lover {loverDiary = ("Antonia ClaudiaBerta Jennyfer L. ",30)}
 *Main> 
 *Main> chain bob $ fmap (*5) (askLover (changeBeloved "Jennyfer L. " (changeBeloved "Berta " (changeBeloved "Claudia" (antonia bob)))) (tellLover 10))
 Lover {loverDiary = ("Paula Antonia ClaudiaBerta Jennyfer L. ",55)}
 *Main> 
> instance Monad Lover where
>     return a = tellMyself a
>     m >>= f = askLover m f 

> whoLovedBy bob = do newLove "Lorenza "
>                     lorenza <- tellMyself 3 
>                     newLove "Antony "
>                     antony <- tellMyself 6 
>                     newLove "Luise "
>                     luise <- tellMyself 2
>                     tellMyself (lorenza + antony + luise)
 *Main> whoLovedBy bob
 Lover {loverDiary = ("Lorenza Antony Luise ",11)}
 *Main> 

- Andrea Rossato