tag:blogger.com,1999:blog-11295132.post115499678320066610..comments2017-11-19T22:29:51.657-08:00Comments on A Neighborhood of Infinity: You Could Have Invented Monads! (And Maybe You Already Have.)Dan Piponihttps://plus.google.com/107913314994758123748noreply@blogger.comBlogger71125tag:blogger.com,1999:blog-11295132.post-76804136027159631822017-10-25T06:44:56.073-07:002017-10-25T06:44:56.073-07:00Hi Dan,
Thanks for the fabulous explanation. Best...Hi Dan,<br /><br />Thanks for the fabulous explanation. Best explanation about monad on the Internet for sure :-) Just a small question:<br /><br /><i>return 64 >>= (\x -> sqrt' x) >>= (\y -> cbrt' y)</i><br /><br />should be<br /><i>return [64] >>= (\x -> sqrt' x) >>= (\y -> cbrt' y) </i><br /><br />right?Quang Tranhttps://www.blogger.com/profile/01663945865787500307noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-6457760274950235642017-05-19T19:12:45.539-07:002017-05-19T19:12:45.539-07:00I have one question with the concept of lifting. I...I have one question with the concept of lifting. In example 1: lets say I have a "normal" function, h and I lift it with the unit function provided, I get h' which returns an empty string as the debug string. So if it is composed with other debuggable functions f' and g', the debug statement of h' is lost..<br />How to solve it?avinashhttps://www.blogger.com/profile/02910077250058350707noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-37670380893579048522016-09-15T04:14:08.383-07:002016-09-15T04:14:08.383-07:00Shouldn't a → b actually be a → StdGen -> b...Shouldn't a → b actually be a → StdGen -> b in the following line:<br /><br />So a function that is conceptually a randomised function a → b can be written as a function a → StdGen -> (b,StdGen) where StdGen is the type of the seed.<br /><br />Or does the use of conceptually there mean something stronger than I am expecting?Ivan Malisonhttps://www.blogger.com/profile/09542111620320995497noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-17003097484345057112016-06-24T18:39:57.682-07:002016-06-24T18:39:57.682-07:00Totally doesn't make sense, sorryTotally doesn't make sense, sorryValery Gavrilovhttps://www.blogger.com/profile/06941058272292020692noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-15561343891649416862015-05-30T16:40:27.708-07:002015-05-30T16:40:27.708-07:00Is the function unit an association of value x wit...Is the function unit an association of value x with some mempty value ( which in our case is empty string? ) from monoidal category?<br /><br />unit x = (x,"")Misha Chavarhahttps://www.blogger.com/profile/06901272601798510274noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-90141023181577235042015-04-04T07:49:57.262-07:002015-04-04T07:49:57.262-07:00I'm at the same place Chris was regarding the ...I'm at the same place Chris was regarding the Random description. Even before the first exercise in this section you say:<br /><br /><br />We now must work out how to compose two randomised functions, f and g. The first element of the pair that f returns needs to be passed in as an input to g. But the seed returned from the g also needs to be passed in to f. Meanwhile the 'real' return value of g needs to be passed in as the first argument of f. So we can give this signature for bind:<br /><br /><br />This implies, to me, a cycle. The output of f is used as input to g and the output of g is then used as input to f. Why would that be the case?<br /><br />Then you state that the signature of bind is:<br /><br />bind :: (a → StdGen → (b,StdGen)) → (StdGen → (a,StdGen)) → (StdGen → (b,StdGen))<br /><br />I don't get this one. Perhaps because I didn't understand the previous paragraph. Can you explain why you have bind taking 2 functions in this case instead of one function as in the previous cases? And why would the second be (StdGen -> (a, StdGen))? What is its purpose?Markhttps://www.blogger.com/profile/02765708798346339434noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-88946777962005425272014-10-03T06:08:09.517-07:002014-10-03T06:08:09.517-07:00For the Writer Monad (first example of debug state...For the Writer Monad (first example of debug state); why would you not just solve the problem with a function of the following type:<br /><br />(Result, String) -> (Result, String)<br /><br />The second parameter in the tuple can carry your logging info from function call to the next.<br /><br />This appears simpler to a programmer without Monad experience.Sam Isaacsonhttps://www.blogger.com/profile/02856720364470192009noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-69888657783004054822014-03-26T02:11:07.035-07:002014-03-26T02:11:07.035-07:00This comment has been removed by the author.AngryGamerhttps://www.blogger.com/profile/03263062369175945973noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-87868172062614092262014-03-26T02:10:24.993-07:002014-03-26T02:10:24.993-07:00Confused with the sixth root example. You describe...Confused with the sixth root example. You describe<br />sixth root = sqrt( cubrt x) yet the diagram shows cubrt (sqrt x).AngryGamerhttps://www.blogger.com/profile/03263062369175945973noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-74880761889189815402013-11-14T07:14:49.815-08:002013-11-14T07:14:49.815-08:00Brilliant stuff. This has really helped me. Thanky...Brilliant stuff. This has really helped me. Thankyou !!!<br />This is a very useful tutorial which will never get outdated.<br />So please can the following be fixed for the sake and sanity of<br />future readers (of which I'm sure there will be many)...<br /><br />As DAY and and Pupeno have already said...<br /><br />The piece of code just before exercise two would be more understandable<br />if it said "unit * f' = f' * unit".<br /><br />The original says "unit * f = f * unit = f" which is simply not true if<br />f refers to the same f as mentioned previously in the article (which is what<br />the ready would naturally assume).<br /><br />This hurt my head for a couple of hours before I finally realised it<br />was a mistake (or ambiguous at best).<br /><br />Thanks,johnhttps://www.blogger.com/profile/03502200064229800787noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-72163982990115569502013-11-14T07:13:18.963-08:002013-11-14T07:13:18.963-08:00Brilliant stuff. This has really helped me. Thanky...Brilliant stuff. This has really helped me. Thankyou !!!<br />This is a very useful tutorial which will never get outdated.<br />So please can the following be fixed for the sake and sanity of<br />future readers (of which I'm sure there will be many)...<br /><br />As DAY and and Pupeno have already said...<br /><br />The piece of code just before exercise two would be more understandable if it said "unit * f' = f' * unit".<br /><br />The original says "unit * f = f * unit = f" which is simply not true if "f" refers to the same f as mentioned previously in the article (which is what<br />the ready would naturally assume).<br /><br />This hurt my head for a couple of hours before I finally realised it<br />was a mistake (or ambiguous if you prefer).<br /><br />Thanks,<br />Johnjohnhttps://www.blogger.com/profile/03502200064229800787noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-38257923299182240022013-03-03T04:11:22.548-08:002013-03-03T04:11:22.548-08:00Great Tutorial, thanks!
But I'm confused: In ...Great Tutorial, thanks!<br /><br />But I'm confused: In exercise 6 we are to prove that lift f * lift g = lift (f.g).<br /><br />But, by definition, f . g is not defined (in contrast to exercise 3).Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-45893260485278407402012-05-09T12:13:48.736-07:002012-05-09T12:13:48.736-07:00Great, great article !
it is the only one I have r...Great, great article !<br />it is the only one I have read (and I read some) that defines a monad by what it <i>is</i> rather than by what it <i>does</i>.<br />I had been very frustrated and confused by the what-it-does approach of explaining monads... I even had been wondering if Haskell was not a complicated way to do simple things...<br /><br />So thank you so much !Tanneguyhttps://www.blogger.com/profile/11749586993176681714noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-85173195393146403932012-03-22T12:59:52.010-07:002012-03-22T12:59:52.010-07:00I never comment on these things,
But thanks so muc...I never comment on these things,<br />But thanks so much.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-28009208982081155552012-02-11T05:59:02.631-08:002012-02-11T05:59:02.631-08:00The best tutorial on Monads! - Thank youThe best tutorial on Monads! - Thank youAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-63850939290750748192010-12-31T18:16:42.730-08:002010-12-31T18:16:42.730-08:00For not being a Haskell programmer, I've read ...For not being a Haskell programmer, I've read a fair number of explanations of monads over the past year (I blame Reddit). So far, I've hit two that have helped; an eight-word definition ("Monads provide a generalized interface to sequential computation."), and your exposition I just tripped across.<br /><br />You've managed to take something that is somewhat impenetrable when presented by others and make the concept not merely natural but truly inevitable once we reach a certain level of abstraction. I suspect this means you normally teach math.<br /><br />Anyway, thank you for this.Ray Leehttps://www.blogger.com/profile/00675537654195582090noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-48058064868307250442010-12-13T02:57:27.296-08:002010-12-13T02:57:27.296-08:00Thanks a lot for a great tutorial.
I've been...Thanks a lot for a great tutorial. <br /><br />I've been searching for a while and this is the best one I've found so far, both in books and on the net.Eternalhttps://www.blogger.com/profile/02512322446421154424noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-84086862229362019002010-11-17T15:40:04.427-08:002010-11-17T15:40:04.427-08:00This tutorial is a great introduction to monads as...This tutorial is a great introduction to monads as it starts with the problem and let the reader develop (or even invent) the solution. This helped me a lot, thanks!Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-89084821569886816612010-08-19T07:24:19.904-07:002010-08-19T07:24:19.904-07:00Anonymous,
The version I gave highlights a certai...Anonymous,<br /><br />The version I gave highlights a certain symmetry in the signature. It's of the form X -> F a -> F b. That's slightly hidden in your version. Of course they are equivalent, but it's this symmetry I want people to notice.sigfpehttps://www.blogger.com/profile/08096190433222340957noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-684848420849340442010-08-18T22:07:57.774-07:002010-08-18T22:07:57.774-07:00Is it an academic convention to write your type si...Is it an academic convention to write your type signatures like this?<br /><br />bind :: (a → StdGen → (b,StdGen)) → (StdGen → (a,StdGen)) → (StdGen → (b,StdGen))<br /><br />It would be much, much more clear if you wrote it like this:<br /><br />bind :: (a → StdGen → (b,StdGen)) → (StdGen → (a,StdGen)) → StdGen → (b,StdGen)<br /><br />Obviously the two are equivalent but it looks like you <i>intend</i> for the first one to return a function rather than accept a third argument.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-12074275314913628592010-07-02T05:47:46.971-07:002010-07-02T05:47:46.971-07:00An excellent tutorial. It really helped me a lot i...An excellent tutorial. It really helped me a lot in understanding monads. The key was the 'bind' function with the more natural order of parameters compared to '>>='. The '*' operator really made clear what is going on, and it was really simple to define it in terms of 'bind'. I also liked that you created exercises to force me stop and think, thus helping in the understanding of the concept.<br /><br />On the downside: the wording before the bind function of the random number example needs a little bit of improvement, exercise 7 was the most difficult because of it.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-66143417341071129732010-03-09T13:22:04.934-08:002010-03-09T13:22:04.934-08:00Bravo - what a great tutorial ! I've read abou...Bravo - what a great tutorial ! I've read about a dozen articles and not really understood Monads but this one really hits the nail. Thanks.Andrew Whaleyhttps://www.blogger.com/profile/05346078852977103014noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-16776721071397495472010-03-04T04:34:11.699-08:002010-03-04T04:34:11.699-08:00It would be better to change unit * f = f * unit =...It would be better to change unit * f = f * unit = f in the paragraph above Exercise Two into unit * f' = f' * unit = f'. And a space is missing in f'*g' in the same paragraph.DAYhttps://www.blogger.com/profile/14359320866411018319noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-55121518036084311422009-11-24T01:23:04.451-08:002009-11-24T01:23:04.451-08:00About the do notation, you basically said:
do {le...About the do notation, you basically said:<br /><br />do {let x = y; more code} ==>> (\x -> do more code) y<br /><br />I was confused at first, until I performed the obvious beta reduction:<br /><br />let x = y in do more code<br /><br />This is actually closer to the original do notation, closer to the other rules, and I think a bit clearer.<br /><br />Anyway, thank you. I now have a way to explain monads to my poor C++ colleagues.Loup Vaillanthttp://www.loup-vaillant.frnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-46175663180702319112009-08-06T04:35:31.952-07:002009-08-06T04:35:31.952-07:00Great post, really made monads easy to understand....Great post, really made monads easy to understand. <br /><br />Any chance you could write the same sort of thing on call/cc ?James Brookshttps://www.blogger.com/profile/16899320910026266930noreply@blogger.com