tag:blogger.com,1999:blog-11295132.post7403719901682023510..comments2015-08-27T06:39:07.723-07:00Comments on A Neighborhood of Infinity: The Trivial MonadDan Piponihttps://plus.google.com/107913314994758123748noreply@blogger.comBlogger23125tag:blogger.com,1999:blog-11295132.post-62578667863670148142015-05-16T05:25:20.267-07:002015-05-16T05:25:20.267-07:00I think one can gain some intuition seeing h imple...I think one can gain some intuition seeing h implemented without using g or >>= or other trickery, sort of the raw thing:<br /><br />h :: W Int -> W Int -> W Int<br />h wx wy = bind (\x -> bind (\y -> return (x + y)) wy) wx<br /><br />the most primitive way to use binds to gain access to multiple unwrapped values.strangequarkhttp://www.blogger.com/profile/10256105245522008294noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-79928385979220516122015-01-23T05:10:26.702-08:002015-01-23T05:10:26.702-08:00When you define the increment and wrapping functio...When you define the increment and wrapping function, f :: Int -> W Int, you say that we can't do this. However, I can define this in Haskell. Is this a typo?Indika Piyasenahttp://www.blogger.com/profile/07107911423599966570noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-63205381953065665682011-07-21T01:52:56.372-07:002011-07-21T01:52:56.372-07:00Thank you! I really, really enjoyed the exercises,...Thank you! I really, really enjoyed the exercises, especially proving the Monad laws and writing "join": that was the only one where I got so stuck that I had to write the types out on paper.<br /><br />Luckily I had the intuition to write out the type for bind, then try to get m (m a) on one side and m a on the other! It was fun.openidhttp://sairyx.org/openid?id=117546008235945914872noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-36969604455102298352010-05-23T08:59:23.692-07:002010-05-23T08:59:23.692-07:00ur right, and it's an awesome tutorial. sorry ...ur right, and it's an awesome tutorial. sorry I didn't say that in the first place!Matthew Kane Parkerhttp://www.blogger.com/profile/17545396524154679147noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-90586984133243658042010-05-22T16:08:09.071-07:002010-05-22T16:08:09.071-07:00Matthew,
It's cool that people are now identi...Matthew,<br /><br />It's cool that people are now identifying places where they can use Applicative instead of Monad. (Scroll up, you're not the first.) But this is intended as a Monad tutorial. I haven't written an Applicative tutorial yet. :-)sigfpehttp://www.blogger.com/profile/08096190433222340957noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-88308321706912597152010-05-22T15:58:44.196-07:002010-05-22T15:58:44.196-07:00for the 2nd question, defining h, the use of monad...for the 2nd question, defining h, the use of monad is overkill (and cumbersome). a discussion of applicative is warranted, since making W an instance of Applicative would allow you to define h quite naturally: <br /><br />h x y = (+) <$> x <*> y<br /><br />which looks a lot more like simple addition ((+) x y) than any of the monadic equivalents:<br /><br />h x y = x >>= \x' -> y >>= y' -> return (x' + y')Matthew Kane Parkerhttp://www.blogger.com/profile/17545396524154679147noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-22092002976114693772010-04-05T14:05:44.419-07:002010-04-05T14:05:44.419-07:00@Moritz: In this case, nothing prevents people fro...@Moritz: In this case, nothing prevents people from writing an unwrapper, but often the data constructor will not be exported from a module, and so not be visible, as it is here.BorisTheBladehttp://www.blogger.com/profile/09024392832854766007noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-51718554301761741292009-05-27T18:58:47.983-07:002009-05-27T18:58:47.983-07:00typo:
We we need to providetypo: <br />We we need to provideAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-48121169936973823052009-05-19T17:05:19.067-07:002009-05-19T17:05:19.067-07:00Hi, great post and very helpful in developing an i...Hi, great post and very helpful in developing an intuition. One difficulty is that at the point you introduced the exercises, you had defined 'bind' but not (>>=), yet you give the solutions in terms of (>>=).Mike M.http://www.blogger.com/profile/10332487203149978380noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-53179281541728929112008-04-05T21:53:00.000-07:002008-04-05T21:53:00.000-07:00For exercises 1 and 2, using only functions define...For exercises 1 and 2, using only functions defined up to those exercises:<BR/><BR/>exercise 1: <BR/>g x my = fmap (+x) my<BR/><BR/>exercise 2: <BR/>h w1 w2 = bind (\x -> fmap (+x) w2) w1<BR/><BR/>I have <A HREF="http://dauclair.blogspot.com/2008/04/trivial-monad-solutions.html" REL="nofollow">an apologetic blog entry</A> discussing those solutions, the loquacious review process may be helpful to monad neophytes, should they be looking for an alternative approach to the solutions given here.geophfhttp://www.blogger.com/profile/09936874508556500234noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-38630396038927670492008-01-04T18:49:00.000-08:002008-01-04T18:49:00.000-08:00Thanks, this article has been a huge help. In par...Thanks, this article has been a huge help. In particular it has helped clarify the relationship between >>= and composition. I still don't like the syntax of >>= but, I can get around that now. I did suffer some frustration from not understanding that type definitions cannot be entered interactively and wasted a little time getting around that. A little note in the next revision might be of help. Anyway, I look forward to the next installment.Ralphhttp://www.blogger.com/profile/03021114177184971018noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-45722296108286606962007-06-21T20:30:00.000-07:002007-06-21T20:30:00.000-07:00Moritz,When I talk about managing tainted data I'm...Moritz,<BR/><BR/>When I talk about managing tainted data I'm not describing some kind of secure programming, just as a 'private' member of a C++ class doesn't prevent people accessing private members through pointer trickery. The point is that if you have a block of code that uses only the monad interface you can reason about what data is 'tainted' really easily. You're free to access that data directly, rather than through the monad API. But at that point the useful theorems about monads no longer apply so it's going to be harder to figure out what is and isn't tainted.sigfpehttp://www.blogger.com/profile/08096190433222340957noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-33132539580552471782007-06-14T14:13:00.000-07:002007-06-14T14:13:00.000-07:00What prevents anybody from writing an unwrapper:un...What prevents anybody from writing an unwrapper:<BR/><BR/>unwrap W x = x<BR/><BR/>Or something?Moritzhttp://moritz.faui2k3.org/en/noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-40707754600335459082007-05-01T20:26:00.000-07:002007-05-01T20:26:00.000-07:00I took the long way around with looking up liftM2...I took the long way around with looking up liftM2's definition in 'do' syntax, untangling the 'do' notation, then smacking my head for not realizing how to unwrap that first monad. From there it was pretty simple to see how g fit in there.<BR/><BR/>Monads click with me, thanks in no small part to all these tutorials ... now to learn Monad Transformers, Arrows and Comonads. And fundeps, and GADTs and a Partridge in a Pear Tree... It's weightlifting for the brain, Haskell is.Chuckhttp://www.blogger.com/profile/12403744972060658849noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-9579858494276190152007-05-01T13:31:00.000-07:002007-05-01T13:31:00.000-07:00Chuck,I only just got around to doing my own exerc...Chuck,<BR/><BR/>I only just got around to doing my own exercises(!!) and I have to admit that they made me pause for a bit. Here's a hint: use 'g' in the definition of 'h'. If you do that then 'h' looks a lot like 'g'.<BR/><BR/>I'll put the answers in my next blog post - mainly because I'll be using them.sigfpehttp://www.blogger.com/profile/08096190433222340957noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-83004256567632306382007-05-01T13:26:00.000-07:002007-05-01T13:26:00.000-07:00I feel hopelessly stupid, as I've been stuck on de...I feel hopelessly stupid, as I've been stuck on defining h for more than an hour now. I even know that :<BR/><BR/>h = liftM2 (+)<BR/><BR/>but I'll be damned if I can actually define it from first principles.Chuckhttp://www.blogger.com/profile/12403744972060658849noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-72179797542985080492007-05-01T12:50:00.000-07:002007-05-01T12:50:00.000-07:00> I guess I would be similarly confused by automat...> I guess I would be similarly confused by automatic lifting.<BR/><BR/>So would I. This is why I think it's still a challenge for programming languages. Someone needs to find a way to do this that isn't confusing and still allows explicit control when needed.sigfpehttp://www.blogger.com/profile/08096190433222340957noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-84074607061136423642007-05-01T12:03:00.000-07:002007-05-01T12:03:00.000-07:00I have the paper on my desk. Had to consult it to ...I have the paper on my desk. Had to consult it to define <*>. *blush*<BR/><BR/>Applicative and Traversable are already included in GHC, but I don't know if they are included by the other compilers. It would be a shame if they weren't included in a future set of standard haskell libraries though. <BR/><BR/>I've skimmed the paper a couple of times, but haven't used the ideas in real code yet. They seem to promise very elegant code. And that, to me, is probably the most important thing with haskell.<BR/><BR/>Automatically lifted functions and values would be sweet. It could perhaps lead to some obfuscation a la operator overloading in c++. I already feel a bit confused over what >>= does sometimes since it depends on what monad I'm in at the moment. I guess I would be similarly confused by automatic lifting. Then again, perhaps both >>= and automatic lifting are things you just get used to.Niclashttp://www.blogger.com/profile/10891748141918429638noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-90891433878655748242007-05-01T11:00:00.000-07:002007-05-01T11:00:00.000-07:00Niclas,'Applicative' is nice. If you dig out the o...Niclas,<BR/><BR/>'Applicative' is nice. If you dig out the original paper you'll see they propose a great syntax for applicatives, but I don't think it ever made its way into official release of Haskell.<BR/><BR/>I think the biggest thing waiting to be invented for Haskell is a way to apply things like liftM implicitly. I think 'Applicative' is a step in the right direction.sigfpehttp://www.blogger.com/profile/08096190433222340957noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-19882889295388043452007-05-01T10:53:00.000-07:002007-05-01T10:53:00.000-07:00Thanks for the exercises. Defining h really got me...Thanks for the exercises. Defining h really got me to appreciate the functions in Control.Monad, especially the liftM* family =)<BR/><BR/>The problem with liftM* is, imho, the ugliness of having to use different functions depending on the arity of the lifted function. Perhaps that's what Control.Applicative is for?<BR/><BR/>instance Applicative W where<BR/> pure = return<BR/> ff <*> fx = ap ff fx<BR/><BR/>g x wy = pure (+) <*> pure x <*> wy<BR/>h wx wy = pure (+) <*> wx <*> wy<BR/><BR/>Yes! Beautiful.Niclashttp://www.blogger.com/profile/10891748141918429638noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-49763956442024783242007-05-01T09:25:00.000-07:002007-05-01T09:25:00.000-07:00Maybe he looked at the source for Control.Monad.Id...Maybe he looked at the source for <B>Control.Monad.Identity</B>.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-7894123364097054402007-04-30T09:17:00.000-07:002007-04-30T09:17:00.000-07:00Kevin,I hope you didn't cheat!Kevin,<BR/><BR/>I hope you didn't cheat!sigfpehttp://www.blogger.com/profile/08096190433222340957noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-79598650929048713722007-04-28T13:16:00.000-07:002007-04-28T13:16:00.000-07:00join m = m >>= idjoin m = m >>= idKevinhttp://www.blogger.com/profile/07426867900304204157noreply@blogger.com