Difference between revisions of "Meet Bob The Monadic Lover"
Jump to navigation
Jump to search
Tomjaguarpaw (talk | contribs) (Delete absurd tutorial) |
|||
Line 1: | Line 1: | ||
− | ==Meet Bob The Monadic Lover== |
||
− | |||
− | '''Note: The source of this page can be used as a Literate Haskell 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: |
||
− | <haskell> |
||
− | |||
− | > newtype Lover a = Lover { loverDiary :: (Name,a) } |
||
− | > deriving (Show) |
||
− | > type Name = String |
||
− | |||
− | </haskell> |
||
− | |||
− | 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: |
||
− | <haskell> |
||
− | |||
− | > createLover name times = Lover (name,times) |
||
− | > startAffairWith name (Lover (names,times)) = Lover (name,0) |
||
− | |||
− | </haskell> |
||
− | |||
− | 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 type of a chick and hates |
||
− | Bob's past, as you can imagine... But, let's face it, Bob is not a saint, |
||
− | after all, and I frankly understand her. |
||
− | |||
− | If you want you can visualize "startAffairWith" with the name of the |
||
− | person you are starting a relationship with: |
||
− | |||
− | <haskell> |
||
− | |||
− | > jenny = startAffairWith "Jenny " |
||
− | > luisa = startAffairWith "Luisa " |
||
− | > antonia = startAffairWith "Antonia " |
||
− | |||
− | </haskell> |
||
− | |||
− | 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 my friend Bob: |
||
− | |||
− | <haskell> |
||
− | |||
− | > bob = createLover "Paula " 5 |
||
− | |||
− | </haskell> |
||
− | |||
− | 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'll just be quite, |
||
− | but in the end... |
||
− | |||
− | What I mean is that Bob is quite proud of his past record and would |
||
− | like to see that 5 increased, not erased! 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... |
||
− | |||
− | <haskell> |
||
− | |||
− | > oneMoreTime (Lover (name,times)) = Lover (name,times + 1) |
||
− | |||
− | </haskell> |
||
− | |||
− | oneMoreTime does what it says, and does 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 a type that seems not really believe in |
||
− | the "Real Love", if you know what I mean. |
||
− | |||
− | Indeed he needs one more method: |
||
− | |||
− | <haskell> |
||
− | |||
− | > changeBeloved newname (Lover (name,times)) = Lover (name ++ newname,times) |
||
− | |||
− | </haskell> |
||
− | |||
− | 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 ",7)} |
||
− | *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 also 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 like to increase the number of |
||
− | "pieces" in their collection. Their lovers, indeed, are just "pieces". |
||
− | |||
− | I mean, 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 than me. |
||
− | |||
− | Anyway we need a new method, for those kind of types like Bob. This |
||
− | method 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: |
||
− | |||
− | <haskell> |
||
− | |||
− | > chainAffairs (Lover (names,oldtimes)) (Lover (newlady,newtimes)) = Lover (newlady++names,newtimes+oldtimes) |
||
− | |||
− | </haskell> |
||
− | |||
− | 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, without having to write |
||
− | "oneMoreTime" so many times. This is especially true with a kind of a |
||
− | type like our Bob, whose activity can be quite difficult to track. |
||
− | |||
− | 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 a 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: |
||
− | |||
− | <haskell> |
||
− | |||
− | > times f (Lover (name,times)) = Lover (name, f times) |
||
− | |||
− | </haskell> |
||
− | |||
− | 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 |
||
− | sexual-intercourse 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: |
||
− | |||
− | <haskell> |
||
− | |||
− | > class Macho f where |
||
− | > chain :: (Num a) => f a -> f a -> f a |
||
− | |||
− | </haskell> |
||
− | |||
− | It is plain obvious that a lover of the kind of Bob must be an |
||
− | instance of this class: |
||
− | |||
− | <haskell> |
||
− | |||
− | > instance Macho Lover where |
||
− | > chain mychicks = chainAffairs mychicks |
||
− | |||
− | </haskell> |
||
− | |||
− | 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 is 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: |
||
− | |||
− | <haskell> |
||
− | |||
− | > instance Functor Lover where |
||
− | > fmap f = times f |
||
− | |||
− | </haskell> |
||
− | |||
− | 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> |
||
− | |||
− | Well, is Bob just that? I mean, I know him and he can be the worst |
||
− | kind of a type, I'm totally aware of that. No doubt. But, you know, |
||
− | there are times when Bob and I hang together, and with me he's not |
||
− | just telling bull... you got it. |
||
− | |||
− | Sometimes I find him alone in his huge, empty apartment down town, |
||
− | staring at the full moon and almost crying in despair... Sometimes he |
||
− | opens up with me, and starts telling me whom he really loved. You |
||
− | won't believe it, I'm sure, but once he said that Paula didn't count |
||
− | anything in his life. I've said it all! |
||
− | |||
− | Now, I'm sure that when he's alone, Bob talks with himself about |
||
− | himself. He's not just a Macho Functor who sums up story after story |
||
− | as a calculating machine. He judges his love, I doesn't say "I |
||
− | changed my beloved" or stuff like that. I'm sure he's able to love. |
||
− | Sometimes. |
||
− | |||
− | I'd like to be there when Bob talks with his soul. I'd like to hear |
||
− | the soul asking Bob about his lovers. And I'd like to see if in these |
||
− | occasions Bob uses the same methods, with himself. |
||
− | |||
− | I'm sure you know what I mean. You too have a soul you talk with. And |
||
− | you know that your soul knows it all. You don't need to talk with her |
||
− | as you would with me. She knows part of your answers, because you two |
||
− | guys, whether you want it or not, share the same past, the same |
||
− | memories. This is you, after all. And you know better then I do. Am I |
||
− | right? |
||
− | |||
− | I don't want to start doing philosophy. This is not the place. But you |
||
− | must agree that it would be unjust to believe that Bob is just a Macho |
||
− | Functor. You must concede that Bob is something more. He is a soul |
||
− | talking with Bob's self... Call it ego, call it psyche, call it as you |
||
− | want, but you perfectly know what we are talking about. Do not |
||
− | lie to yourself! |
||
− | |||
− | Ahh, who was that philosopher that said that lying to others is the |
||
− | exception. The rule is lying to ourselves. Friedrich what? I don't |
||
− | remember anymore... |
||
− | |||
− | Ok, let's stop with all this bull... ops, I start talking like Bob! |
||
− | |||
− | Let's go on and see how we can express this human behavior that Bob |
||
− | seems to have, sometimes. |
||
− | |||
− | We said that the soul asks Bob, but that the soul knows part of the |
||
− | answer. So the answer must imply something the soul knows. In other |
||
− | word, the answer must be some kind of partial application, right? |
||
− | |||
− | So let's write this first: |
||
− | |||
− | <haskell> |
||
− | |||
− | > tellLover newtimes oldtimes = Lover ("", newtimes+oldtimes) |
||
− | |||
− | </haskell> |
||
− | |||
− | And now the question: |
||
− | |||
− | <haskell> |
||
− | |||
− | > askLover lover answer = Lover (oldnames ++ newname,newtimes) |
||
− | > where (oldnames,oldtimes) = loverDiary lover |
||
− | > (newname,newtimes) = loverDiary (answer oldtimes) |
||
− | |||
− | </haskell> |
||
− | |||
− | This seems to be just fine to me. "askLover" takes a partial answer |
||
− | and fills it with the missing part (oldtimes) in the where clause: the |
||
− | soul's memory, extracted from the loverDiary of the lover, memory that |
||
− | Bob and his soul share, is added to the partial answer. |
||
− | |||
− | But, we said, this is just what we see. When Bob's soul is alone |
||
− | with herself, I mean, inside Bob, who is probably sitting somewhere |
||
− | all stoned and drunk, this soul needs some methods to talk to herself |
||
− | about new loves and new times. |
||
− | |||
− | So, let's write these soul's methods: |
||
− | |||
− | <haskell> |
||
− | |||
− | > tellMyself newtimes = Lover ("", newtimes) |
||
− | > newLove love = Lover (love,0) |
||
− | |||
− | |||
− | </haskell> |
||
− | |||
− | To me that seems to be enough. Well, just give it a try: |
||
− | |||
− | *Main> askLover (tellMyself 10) (tellLover 1) |
||
− | Lover {loverDiary = ("",11)} |
||
− | |||
− | Well, this for sure is not Bob! Look at this poor soul of a type. 11 |
||
− | dates and no names. Sounds suspicious to me... This guy, all alone, |
||
− | doing what?? |
||
− | |||
− | I'd have a name for such a "spirit"! Remember that German philosopher |
||
− | who was talking of this stuff all alone, the essence... I don't |
||
− | remember his name but if you look up at the |
||
− | [http://en.wikipedia.org/wiki/Leibniz#The_Monads Wikipedia] something |
||
− | could come up. |
||
− | |||
− | Let's try again: |
||
− | |||
− | *Main> askLover (newLove "Lory ") (tellLover 1) |
||
− | Lover {loverDiary = ("Lory ",1)} |
||
− | |||
− | Well this is not Bob. I don't know him personally. But he doesn't seem |
||
− | such an interesting guy, judging from numbers (you know, the macho |
||
− | functor stuff). |
||
− | |||
− | So here's Bob: |
||
− | |||
− | *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> |
||
− | |||
− | Now I recognize him. The old dear Bob. What a type. |
||
− | |||
− | Be careful, with this stuff, though. Do not pretend it being the truth |
||
− | about Bob. When Bob tells something aloud to his soul you never know |
||
− | what he's talking about. Truth is not what Bob likes most. |
||
− | |||
− | You sure know that by now! |
||
− | |||
− | Just to show, this is Bob a couple of weeks ago. We went over to one |
||
− | of his friends, and he started, as usual, talking about what kind of a |
||
− | type of a lover he is, showing off names I would not dare to write |
||
− | here. |
||
− | |||
− | Just a couple of examples: |
||
− | |||
− | *Main> fmap (*3) chain bob (askLover (changeBeloved "Jennyfer L. " (changeBeloved "Berta " (changeBeloved "Claudia " (antonia bob)))) (tellLover 10)) |
||
− | Lover {loverDiary = ("Paula Antonia Claudia Berta Jennyfer L. ",45)} |
||
− | *Main> fmap (*3) $ askLover (changeBeloved "Jennyfer L. " (changeBeloved "Berta " (changeBeloved "Claudia " (antonia bob)))) (tellLover 10) |
||
− | Lover {loverDiary = ("Antonia Claudia Berta Jennyfer L. ",30)} |
||
− | *Main> chain bob $ fmap (*5) (askLover (changeBeloved "Jennyfer L. " (changeBeloved "Berta " (changeBeloved "Claudia " (antonia bob)))) (tellLover 10)) |
||
− | Lover {loverDiary = ("Paula Antonia Claudia Berta Jennyfer L. ",55)} |
||
− | *Main> |
||
− | |||
− | Would you believe it? Certainly I don't. |
||
− | |||
− | Why? Because I happen to know Bob better then you! |
||
− | |||
− | Well, all this soul stuff looks interesting. We could have some fun |
||
− | with it. |
||
− | |||
− | For sure now we can build female lovers who are not just ... partial |
||
− | applications. |
||
− | |||
− | Introducing Alessia: |
||
− | |||
− | *Main> let alessia = askLover (newLove "Joseph ") (tellLover 4) |
||
− | *Main> alessia |
||
− | Lover {loverDiary = ("Joseph ",4)} |
||
− | *Main> |
||
− | |||
− | And what about the bird of a new soul without any memory and |
||
− | experience. |
||
− | |||
− | Sorry, but I find English not expressive enough for what I mean. Well, |
||
− | I'll admit that it could be just me. But how do you guys say when |
||
− | someone is going to, you know, be born? As far as my English goes |
||
− | "born" is the past participle of "bear". This is fine, but I believe |
||
− | it's just the woman's perspective. She bears what is going to be born. |
||
− | |||
− | Ok, let's start from a pregnant woman. I must confess I do not have |
||
− | very much experience in this field, but I would probably express |
||
− | pregnancy this way: |
||
− | |||
− | *Main> askLover (askLover (newLove "Bob ") (tellLover 0)) (tellLover 1) |
||
− | Lover {loverDiary = ("Bob ",1)} |
||
− | *Main> |
||
− | |||
− | I don't know if it does make sense. But for sure pregnancy doesn't |
||
− | make any sense to Bob. So, possibly, this is the right way to express |
||
− | it. At least when talking about Bob. |
||
− | |||
− | But I need a name for this method: the act of the birth. We need a |
||
− | future participle, this is what we really need. You know, something |
||
− | like the Latin "naturum" (is to be born), the Greek physis, the |
||
− | Italian nascita or natura. |
||
− | |||
− | Yes, something like "nature" seems to be appropriate. But, just to |
||
− | keep it apart from the "real nature" (if such a thing exists), like |
||
− | wildness and stuff like that (Bob lives down town and hates everything |
||
− | that even seems "natural"), we will use the Greek term physis. |
||
− | |||
− | Also as an homage to that Greek philosopher, [http://en.wikipedia.org/wiki/Heraclitus Eraclo, Heracloto], I don't |
||
− | remember, that used to say: "Physis kryptestai phylein" (nature loves |
||
− | to hide herself). |
||
− | |||
− | <haskell> |
||
− | |||
− | > physis = Lover ([],0) |
||
− | |||
− | </haskell> |
||
− | |||
− | Let's try it: |
||
− | |||
− | *Main> let andrea = physis |
||
− | *Main> andrea |
||
− | Lover {loverDiary = ("",0)} |
||
− | *Main> |
||
− | |||
− | Ok, seems to be working. And also the name seems appropriate. Before |
||
− | his birth, he was not. During the evaluation of his "going to be born" |
||
− | he became a "definitely born". |
||
− | |||
− | And how a Lover dies? This is simple: |
||
− | |||
− | <haskell> |
||
− | |||
− | > dies lover = Lover ([],0) |
||
− | |||
− | </haskell> |
||
− | |||
− | *Main> let alessia = askLover (newLove "Joseph ") (tellLover 4) |
||
− | *Main> alessia |
||
− | Lover {loverDiary = ("Joseph ",4)} |
||
− | *Main> dies alessia |
||
− | Lover {loverDiary = ("",0)} |
||
− | *Main> |
||
− | |||
− | Seems to work to me. |
||
− | |||
− | I know what you are going to say now. How can you tell who's just born |
||
− | from who's just died? |
||
− | |||
− | Be careful with this kind of arguments with me. I can be even more |
||
− | demanding. For instance, look at this guy: |
||
− | |||
− | *Main> askLover (tellMyself 0) (tellLover 0) |
||
− | Lover {loverDiary = ("",0)} |
||
− | *Main> |
||
− | |||
− | Can you tell me whether he is alive or dead? |
||
− | |||
− | If you cannot, you'd better start asking yourself a few questions. |
||
− | |||
− | If you can, I'm sure you are going to come up with something funny, |
||
− | like "This guy gotta be a priest!". |
||
− | |||
− | Anyway is far from being a lover, and a kind of a type like Bob would |
||
− | not spend a single second the have a conversation with him. |
||
− | |||
− | From our perspective, though, there are no differences at all. But |
||
− | for a Macho Functor Lover, well, being dead turns out to be a huge |
||
− | loss. Take it for granted! |
||
− | |||
− | I like playing this game, Haskell let us create quite interesting kinds |
||
− | of types. I was thinking, do you remember that guy in that movie? |
||
− | |||
− | How was titled? [http://www.imdb.com/title/tt0209144/ Memento] I think. |
||
− | |||
− | This Leonard kind of a type, who, when falls asleep, looses all his |
||
− | short term memory... I'd like to introduce this kind of type. |
||
− | |||
− | I think this is going to be an easy type: |
||
− | |||
− | <haskell> |
||
− | |||
− | > newtype Leonard a = Leonard { leonardDiary :: (Name,a) } |
||
− | > deriving (Show) |
||
− | |||
− | > askLeonard lover answer = Leonard (oldnames,oldtimes) |
||
− | > where (oldnames,oldtimes) = leonardDiary lover |
||
− | > (newname,newtimes) = leonardDiary (answer oldtimes) |
||
− | |||
− | > leonard = Leonard ("Jorja Fox", 1000) |
||
− | |||
− | > tellLeonard newtimes oldtimes = Leonard ("", newtimes+oldtimes) |
||
− | > tellLeonardSelf newtimes = Leonard ("", newtimes) |
||
− | > newLeonardLove love = Leonard (love,0) |
||
− | |||
− | </haskell> |
||
− | |||
− | I believe this is him. Well, just try: |
||
− | |||
− | *Main> askLeonard (leonard) (tellLeonard 100000000) |
||
− | Leonard {leonardDiary = ("Jorja Fox",1000)} |
||
− | *Main> |
||
− | |||
− | Seems to be Leonard to me. Definitely. |
||
− | |||
− | What do you think, could this kind of a type be a Macho? I believe he can: |
||
− | |||
− | <haskell> |
||
− | |||
− | > instance Macho Leonard where |
||
− | > chain (Leonard (a,b)) (Leonard (c,d)) = (Leonard (a,b)) |
||
− | |||
− | </haskell> |
||
− | |||
− | Sure he can. Look here: |
||
− | |||
− | *Main> chain leonard (askLeonard (newLeonardLove "Angolie ") (tellLeonard 3)) |
||
− | Leonard {leonardDiary = ("Jorja Fox",1000)} |
||
− | *Main> |
||
− | |||
− | This is definitely the Leonard type. |
||
− | |||
− | Now I'm asking to myself if Leonard can also be considered a Functor. |
||
− | |||
− | Yes, I do believe he can: |
||
− | |||
− | <haskell> |
||
− | |||
− | > instance Functor Leonard where |
||
− | > fmap f (Leonard (a,b)) = Leonard (a,f b) |
||
− | |||
− | </haskell> |
||
− | |||
− | Try him: |
||
− | |||
− | *Main> fmap (+6) (chain leonard (askLeonard (newLeonardLove "Angolie ") (tellLeonard 3))) |
||
− | Leonard {leonardDiary = ("Jorja Fox",1006)} |
||
− | *Main> |
||
− | |||
− | A bit strange, isn't it? Seems like Leonard was thinking to do it with |
||
− | Jorja... Well, perhaps this is because he's awake. Just wait for him |
||
− | to go to sleep and check again when he wakes up. Otherwise, well, my fault! |
||
− | |||
− | Ohh gosh! I'm sure now you are starting to believe I'm going to build up a |
||
− | [http://www.imdb.com/title/tt0133093/ Matrix]! |
||
− | |||
− | No, I'm not. We'd better go back to our [http://www.imdb.com/title/tt0120601/ Being John Malchowich] |
||
− | style. Right? |
||
− | |||
− | Now we can say that Bob, after all, seems to have a soul. Great! The |
||
− | problem, now, is to find a suitable Haskell class for this kind of |
||
− | Lovers, who are not just Macho Functors. |
||
− | |||
− | It seems that Haskell developers were quite aware that this need could |
||
− | show up, and they created that class called Monad class. |
||
− | |||
− | I must tell you the truth: I don't know if I like that name. Anyway, |
||
− | sometimes I think it sounds good. In Italian "monade" sounds a bit |
||
− | like "modo", "mode" "modality", you know, that kind of sound. Sure I |
||
− | was told it comes from Greek and all that. But a name is first a |
||
− | sound. Only secondly a meaning. And what Monad means, well, we know: |
||
− | it's a kind of a type like our Bob. Seems just a Macho Functor, but |
||
− | has an inside ... side. This doing questions and doing answering going |
||
− | on. |
||
− | |||
− | So I could say I like the "monad" name, because its sound makes me |
||
− | remember the it could mean "a way of doing something". And I believe |
||
− | that we are, after all, just the way we do... |
||
− | |||
− | I like this "do" word too. In Italian we don't have something you can |
||
− | put everywhere and it always seems to fit in. It doesn't matter if it |
||
− | really doesn't. It seems it does. |
||
− | |||
− | So, when I think of a kind of a type like a "monad" I always start |
||
− | thinking about ways of doing something, you know, all the questioning |
||
− | and answering, and telling oneself, and so on. |
||
− | |||
− | I believe that the Haskell developers had similar feelings, as it |
||
− | will turn out. |
||
− | |||
− | By the way, first let's check if Bob can really be expressed by the |
||
− | monad class. |
||
− | |||
− | I mean, is this true? |
||
− | |||
− | <haskell> |
||
− | |||
− | > instance Monad Lover where |
||
− | > return a = tellMyself a |
||
− | > m >>= f = askLover m f |
||
− | |||
− | </haskell> |
||
− | |||
− | Well, let's check it. Want to see a drunk Bob? |
||
− | |||
− | <haskell> |
||
− | |||
− | > drunk bob = do newLove "Paula " |
||
− | > paula <- tellMyself 5 |
||
− | > newLove "Jennifer L. " |
||
− | > jennyfer <- tellMyself 10 |
||
− | > newLove "Britney S. " |
||
− | > brit <- tellMyself 20 |
||
− | > newLove "Alex " |
||
− | > alex <- tellMyself 15 |
||
− | > tellMyself (jennyfer * brit * alex) |
||
− | |||
− | </haskell> |
||
− | |||
− | Let's try: |
||
− | |||
− | *Main> drunk bob |
||
− | Lover {loverDiary = ("Paula Jennifer L. Britney S. Alex ",3000)} |
||
− | *Main> |
||
− | |||
− | This is definitely the drunk Bob I know. |
||
− | |||
− | So it's true, Haskell provides us with a way of describing the inside |
||
− | side of a soul. All this "do" thing we have just seen. |
||
− | |||
− | Did you see? No more "askingLover" and "tellingLover", just soul's methods |
||
− | such as "tellMyself" and "newLove". |
||
− | |||
− | This is because within that "do-notation" stuff, we are inside our |
||
− | Lover. You can see each line as a soul's answer to an implied soul's |
||
− | question. I told you before, this is Bob's soul talking to herself, |
||
− | without outside-Bob's intervention. |
||
− | |||
− | This is all we have to say about a monad in Haskell: it is just the |
||
− | class of types that happen to have a soul. Or, put it differently, |
||
− | it's the class of types that can be described in terms of their |
||
− | internal side, their doing something to themselves. |
||
− | |||
− | Who can be a member of such an exclusive class? Sure Bob the Macho |
||
− | Functor Lover can. He has a soul, after all. |
||
− | |||
− | So we have some kind of a rule: if you have a soul you are allowed to |
||
− | be a member of this exclusive class of types. If you don't, well, you |
||
− | can be a Macho Functor and nothing more. |
||
− | |||
− | Just to make this point clear, take that nice kind of a type we called |
||
− | the Leonard type. I like him, I must tell you the truth. |
||
− | |||
− | Still, does he have such a soul that will allow him to be a member of |
||
− | our exclusive club, the Monadic class of types? |
||
− | |||
− | Go try yourself: |
||
− | |||
− | <haskell> |
||
− | instance Monad Leonard where |
||
− | return a = tellLeonardSelf a |
||
− | m >>= f = askLeonard m f |
||
− | </haskell> |
||
− | |||
− | If this is true, then Leonard has a soul that fits Haskell definition |
||
− | of a soul. Otherwise... |
||
− | |||
− | Ok, I'm going to tell you anyway: the answer is NO! There must be some |
||
− | kind of regulation, some kind of Law that states that Leonard is unfit |
||
− | for that exclusive club. |
||
− | |||
− | Why? I don't know. |
||
− | |||
− | There must be some kind of a [http://www.mala.bc.ca/~johnstoi/kafka/beforethelaw.htm gatekeeper kind of a type sitting before this Law], |
||
− | and we are not allowed to get in. |
||
− | |||
− | What I'd like to point out is that, deciding whether the poor soul we |
||
− | called Leonard has a soul left or not, is a moral decision, not just a |
||
− | technical one. I'm not sure, but as far as I understand it, this is |
||
− | the central question in the [http://www.imdb.com/title/tt0209144/ movie] |
||
− | where our Leonard does what he does. |
||
− | |||
− | That is to say, if you really believe you are free and you possess |
||
− | self determination (by the way, I do not), you should start asking |
||
− | yourself some questions about Leonard status in Haskell. I'm saying |
||
− | that just to warn you. This decision has been already taken. I'll add, |
||
− | taken away from you. |
||
− | |||
− | Some Haskell guru took that decision for you, and that is it. Period. |
||
− | |||
− | You know, those haskell gurus believe to belong to a superior kind of |
||
− | types. Since they have the power to create souls out of thin air, they |
||
− | came to believe they are some kind of a type of a god. |
||
− | |||
− | Definitely not just monads, as we poor souls are. |
||
− | |||
− | Don't say I didn't tell you: when you start using haskell for your |
||
− | description of the world, keep in mind that in the world you are going |
||
− | to describe types like Leonard are not souls, but just malfunctioning |
||
− | Functors! |
||
− | |||
− | Let's go back to Bob. I promised I would introduce Bob to you, and I |
||
− | think I did it. Still, you could be unsatisfied with my introduction. |
||
− | I said a lot about the outside Bob, and very little about his inside |
||
− | side. I just show you a drunk Bob, not the real Bob's soul. |
||
− | |||
− | You know, the problem is that I can describe only what I know. Pretty |
||
− | obvious. |
||
− | |||
− | What I really wanted to do here, it's just to show you that we could |
||
− | describe Bob's inside if we had enough information. |
||
− | |||
− | And you do not have such information, because you don't know Bob. |
||
− | |||
− | But you know that I do. |
||
− | |||
− | So I'll try to tell you just what I know. If you like it, ok, |
||
− | otherwise, well, your business. |
||
− | |||
− | It was one of those stormy nights and I came over to Bob's apartment, |
||
− | down town, with a couple of bottles of a quite strong red wine. We, I |
||
− | mean me and Bob, hate white wine... females' stuff... And when we are |
||
− | alone, I must confess that, we behave very much like Macho Functors. |
||
− | |||
− | But we are all alone, and nobody can judge us. |
||
− | |||
− | Bob was rolling one of his giant spliff with some weed he got |
||
− | somewhere (he wouldn't tell you where no matter what). |
||
− | |||
− | The radio was playing one of those dreadful Dial Sessions, and when |
||
− | Bird misses the entrance in Lover Man, Bob lit up the joint and |
||
− | stared at me. The sound of an almost dying alto sax was filling the |
||
− | room, mixing with the strong smell of weed when I stared back. |
||
− | |||
− | In that very moment I believed, and still believe, I had a glimpse of |
||
− | Bob's soul. |
||
− | |||
− | I may be wrong, but this is what I believe I saw: |
||
− | |||
− | <haskell> |
||
− | |||
− | > whoLovedBy bob = do newLove "Andrea " |
||
− | > andrea <- tellMyself 1 |
||
− | > newLove "Bob " |
||
− | > bob <- tellMyself 1 |
||
− | > tellMyself (andrea + bob) |
||
− | |||
− | </haskell> |
||
− | |||
− | *Main> whoLovedBy bob |
||
− | Lover {loverDiary = ("Andrea Bob ",2)} |
||
− | *Main> |
||
− | |||
− | Wait a second. This is not true, I'm just kidding... myself. |
||
− | |||
− | In that very moment this is precisely what I saw: |
||
− | |||
− | <haskell> |
||
− | whoLovedBy bob = do newLove "Andrea " |
||
− | andrea <- tellMyself 1 |
||
− | tellMyself (andrea + (whoLovedBy bob)) |
||
− | </haskell> |
||
− | |||
− | This is all I know about Bob. He loves me, but I'm not the only one. |
||
− | |||
− | - [[User:AndreaRossato|Andrea Rossato]] |
||
− | |||
− | [[Category:Tutorials]] |
||
− | [[Category:Idioms]] |
||
− | [[Category:Monad]] |