tag:blogger.com,1999:blog-11295132.post7531218329312814569..comments2024-02-24T01:46:31.188-08:00Comments on A Neighborhood of Infinity: Haskell Monoids and their Usessigfpehttp://www.blogger.com/profile/08096190433222340957noreply@blogger.comBlogger37125tag:blogger.com,1999:blog-11295132.post-8655655578680305652013-01-26T13:01:34.270-08:002013-01-26T13:01:34.270-08:00Great article, as we say in french : ce qui se con...Great article, as we say in french : ce qui se conçoit bien s'énonce clairement. Thanks.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-86595734453891545162011-10-04T05:08:16.597-07:002011-10-04T05:08:16.597-07:00"Also, the stuff about Any being clear on the..."Also, the stuff about Any being clear on the semantics, I don't agree. It's just a suggestive name; it could have semantics of anything really. We still need to read into the code, and now it is FAR far away, hidden somewhere in an instance declaration."<br /><br />Not true, you don't need to read any instance anything (obviously you'll have to know what Monoids are, then you can intuit what Any does). Once you see Any in the signature you know <i>something</i> is getting flagged. You will have to look at the code for that specific function to find out exactly <i>what</i>.<br /><br />"Instead of writing all this bits and pieces in miriad of classes, why not just use a functional approach, and make e.g. foldMap function to accept an explicit functional argument for a combining function?"<br /><br />Haskell already has this if that's all you want (e.g. foldr/foldl). Things like foldMap allow you to get even tighter with your type definitions. The more of your <b>logic</b> you can turn into a type the more the type system can help you find bugs.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-82501216692945464012011-07-15T10:03:25.109-07:002011-07-15T10:03:25.109-07:00Just wanted to add my +1 to this article. Thanks f...Just wanted to add my +1 to this article. Thanks for taking the time to write it!Anonymoushttps://www.blogger.com/profile/18055286161550269129noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-16450952938171152532011-07-06T09:54:26.809-07:002011-07-06T09:54:26.809-07:00@Anonymous Hey! It's not *my* Data.Monoid pack...@Anonymous Hey! It's not *my* Data.Monoid package.<br /><br />I don't believe the sparsity of the documentation has anything to do with elitism. It's missing documentation because Haskell code is largely written by volunteers who have limited time on their hands. I wrote this article to help remedy this fact. I hope it's been of use. Even better might be for me to fold some of what I've written here back into the documentation.<br /><br />I agree that seeing 'Any' on its own means little. But with documentation it makes a great mnemonic.sigfpehttps://www.blogger.com/profile/08096190433222340957noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-62126330808734937232011-07-06T08:23:38.122-07:002011-07-06T08:23:38.122-07:00Reading this plain-languaged excellent clearly-spo...Reading this plain-languaged excellent clearly-spoken clear article makes me real mad about how poorly written is your given Haskell package documentation. Take Data.Monoid for example. This just does NOT parse for anyone coming to read it for the first time.<br /><br />Too Much Elitism among Haskell documentation writers.<br /><br />Also, the stuff about Any being clear on the semantics, I don't agree. It's just a suggestive name; it could have semantics of anything really. We still need to read into the code, and now it is FAR far away, hidden somewhere in an instance declaration. And Haddock isn't really at all good at producing instance documentation, is it, being that it does NOT produce any.<br /><br />Instead of writing all this bits and pieces in miriad of classes, why not just use a functional approach, and make e.g. foldMap function to accept an explicit functional argument for a combining function? That's what's done implicitly anyway, selecting the specific mappend version thru the type dictionary behind the curtain. <br /><br />Is all this typeclass stuff just a distraction really?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-57212731255956981072009-11-24T02:57:21.609-08:002009-11-24T02:57:21.609-08:00@ Qrilka
> And also why are you talking about ...@ Qrilka<br /><br />> And also why are you talking about signatures and adding/pulling out elements? The lists are immutable here I think. Am I wrong?<br /><br />That was just an abuse of language. But saying "producing a result which is the addition/removal of elements of the original list" would sound a bit cumbersome.<br /><br />Note that the exact same abuse of language is made when we are talking about mutable variables: when you "change" a variable, you actually replace the value it contains by another value. The variable itself, as a container, didn't really change. And the value that was previously in it certainly didn't changed at all. You just lost one reference to it.<br /><br />Anyway, <a href="http://www.loup-vaillant.fr/articles/assignment" rel="nofollow" rel="nofollow">assingment is evil</a>, so…Loup Vaillanthttp://www.loup-vaillant.frnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-72178886678109624712009-07-20T23:46:34.994-07:002009-07-20T23:46:34.994-07:00So we finished 1st ussue of our journal and your a...So we finished 1st ussue of our journal and your article is in it - http://fprog.ru/2009/issue1/<br />(Not sure if you can read Russian though)Qrilkahttps://www.blogger.com/profile/14856370078919907461noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-82801304504030698692009-05-09T04:38:00.000-07:002009-05-09T04:38:00.000-07:00And also why are you talking about signatures and ...And also why are you talking about signatures and adding/pulling out elements? The lists are immutable here I think. Am I wrong?Qrilkahttps://www.blogger.com/profile/14856370078919907461noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-73659348950687852492009-05-05T11:27:00.000-07:002009-05-05T11:27:00.000-07:00BTW "to combine [] with any list leaves gives you ...BTW "to combine [] with any list leaves gives you back" maybe "leaves" is unnecessary here?Qrilkahttps://www.blogger.com/profile/14856370078919907461noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-78341619848385946552009-05-03T07:22:00.000-07:002009-05-03T07:22:00.000-07:00Qrilka,
Feel free to make a translation. Link bac...Qrilka,<br /><br />Feel free to make a translation. Link back here and maybe put a link here pointing to the translation.sigfpehttps://www.blogger.com/profile/08096190433222340957noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-28106119549596697262009-05-03T00:12:00.000-07:002009-05-03T00:12:00.000-07:00Dan, I want to translate your post to russian and ...Dan, I want to translate your post to russian and publish (linking to the original text). Do I need make any additional steps from copyright point of view?Qrilkahttps://www.blogger.com/profile/14856370078919907461noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-68086363392237073502009-04-14T14:03:00.000-07:002009-04-14T14:03:00.000-07:00Great post. One minor note:
(Monoid a) => a -&...Great post. One minor note:<br /><br />(Monoid a) => a -> b<br />should be<br />(Monoid a) => a -> a<br /><br />otherwise there is no way the monoid could be changed and a the eval unsafe cast avoided.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-89890147026155123622009-04-11T20:19:00.000-07:002009-04-11T20:19:00.000-07:00As much as everyone else has said this: great arti...As much as everyone else has said this: great article. I'm relatively new to Haskell and this was completely readable.<BR/><BR/>Thank you for sharing!Unknownhttps://www.blogger.com/profile/08425435755112948327noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-48529696834829045772009-02-21T01:24:00.000-08:002009-02-21T01:24:00.000-08:00Thank you for an informative and approachable post...Thank you for an informative and approachable post. The things about Writer was especially helpful for a problem in Haskell that I've been mulling over.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-76412290078200639722009-02-05T09:45:00.000-08:002009-02-05T09:45:00.000-08:00Well, you can certainly rescue some of your blog p...Well, you can certainly rescue some of your blog posts to that end. This one on monoid is perfect really, theory meets practice !<BR/><BR/>Maybe you could team up with <A HREF="http://scienceblogs.com/goodmath/goodmath/programming/haskell/" REL="nofollow">Good Math</A> ? <BR/><BR/>The two of you have already produced quite a bit along those lines.<BR/><BR/>The book would obviously need a concerted approach with respect to the topics presented... <BR/><BR/>I am pretty sure, a lot of newcomers to Haskell would love to read more about the Mathematics lurking behind its powerful features.<BR/><BR/>Maybe it could be self-published, something like Lulu ?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-65382286723698623442009-01-27T14:52:00.000-08:002009-01-27T14:52:00.000-08:00Peter,Any monoid makes Writer a monad. Any commuta...Peter,<BR/><BR/>Any monoid makes Writer a monad. Any commutative monoid makes Writer a commutative monad.<BR/><BR/>Anynoymous,<BR/><BR/>I'd love to collect together a bunch of algebraic programming stuff in a book. But I also know it's a vast amount of work to get a book written. I'd need several months off work.sigfpehttps://www.blogger.com/profile/08096190433222340957noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-74290589135439898272009-01-27T14:34:00.000-08:002009-01-27T14:34:00.000-08:00Wow, I for one would love to see a book full of ma...Wow, I for one would love to see a book full of material like this ! A book exposing Haskell mathematical underpinnings and techniques to harness this power in day to day programming...<BR/>Do you feel up to it?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-54394082649115990752009-01-24T20:15:00.000-08:002009-01-24T20:15:00.000-08:00With the comment about "Any" being clearer than "B...With the comment about "Any" being clearer than "Bool" about the intentions of the code, it seems like it's actually a Good Thing that Haskell requires newtype wrappers to coax different monoids out of the same type.<BR/><BR/>As for Writer and commutativity, I think that to be a monad it has to satisfy the monad "commutativity" law, for which it relies on the monoid's commutativity. Is that right?Peter Berryhttps://www.blogger.com/profile/08770230331776974807noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-15440720143208105772009-01-24T08:11:00.000-08:002009-01-24T08:11:00.000-08:00Thanks for an excellent article, Dan. I normally ...Thanks for an excellent article, Dan. I normally get about halfway through your blog posts before my brain explodes; eliminating all the jargon in your post and explaining all the maths terms helped tremendously. (For example, I know what associativity is, but I always confuse it with commutativity, and it's great that you cater for the dumb folk like me without having to look up all the terms to clarify the terms :). It helps a ton with the flow of the article.)<BR/><BR/>Please keep up writing blog posts targeted at the poor folks like me, who have some Haskell skills but don't really know all the maths jargon!André Panghttps://www.blogger.com/profile/10083178578284485368noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-4938263000305294752009-01-22T12:48:00.000-08:002009-01-22T12:48:00.000-08:00And monads are a monoid object in the category of ...And monads are a monoid object in the category of endofunctors.<BR/><BR/>In the language of the times monoid is a minimalist notion of composition before categorification. Monad is a minimalist notion of composition post categorification.leithaushttps://www.blogger.com/profile/01069099703796397027noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-72889821039960858992009-01-22T06:39:00.000-08:002009-01-22T06:39:00.000-08:00Anonymous,Mooids form a monoidal category in fact....Anonymous,<BR/><BR/>Mooids form a <A HREF="http://en.wikipedia.org/wiki/Monoidal_category" REL="nofollow">monoidal category in fact</A>.sigfpehttps://www.blogger.com/profile/08096190433222340957noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-79159920827758210962009-01-22T05:25:00.000-08:002009-01-22T05:25:00.000-08:00Multiplying monoids gives a product monoid. This i...Multiplying monoids gives a product monoid. This is associative and has a neutral element. So monoids form a monoid :) (up to isomorphism)Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-32232612686017306172009-01-21T08:24:00.000-08:002009-01-21T08:24:00.000-08:00This was an amazingly straightforward yet enlighte...This was an amazingly straightforward yet enlightening article; the section on the 'Product' monoid was particularly novel for me. I would love to see you expand on the concepts you mentioned towards the end, grounded with real-world haskell examples (as you did in this post.) Thanks for writing sigfpe!<BR/><BR/>P.S. In my opinion you just single-handedly resolved the 'Appendable' debate on haskell-cafe with your tree folding examples.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-11295132.post-57430956527786883852009-01-19T10:07:00.000-08:002009-01-19T10:07:00.000-08:00Dan,And when we have a 'notion of composition&...Dan,<BR/><BR/>And when we have a 'notion of composition' (monoid ~ monad) plus a 'notion of collection' (essentially presented as a monad) we can autogenerate a 'relationally complete' logic. <BR/><BR/>m,n ::= e | g1 | ... | gN | m*n<BR/><BR/>That freely generates our monoid terms (for a monoid with N generators), but needs to be whacked down by m*e = m = e*m, m1*(m2*m3) = (m1*m2)*m3 (plus whatever other identities a specific monoid supports). If our 'notion of collection is set', the we get the following logic 'for free'.<BR/><BR/>k,l ::= true | ~k | k&l <BR/> e | g1 | ... | gN | k*l<BR/> for x in k.l | rec x.k | x<BR/><BR/>The boolean connectives at the top come from the fact that we're using set. The 'structural' connectives in the middle come from the monoid structure. The other structure comes from calculations of fixpoints.<BR/><BR/>See <A HREF="http://biosimilarity.blogspot.com/2007/02/algebraic-databases.html" REL="nofollow">algebraic databases</A> for more discussion. Or, <A HREF="http://biosimilarity.blogspot.com/2009/01/3-applications-of-indexed-composition.html" REL="nofollow">indexed compositions</A> for applications.leithaushttps://www.blogger.com/profile/01069099703796397027noreply@blogger.comtag:blogger.com,1999:blog-11295132.post-78273577171527061142009-01-18T15:49:00.000-08:002009-01-18T15:49:00.000-08:00Here's a possible solution to the min/max prob...Here's a possible solution to the min/max problem:<BR/><BR/>This part ought to be in a library:<BR/><BR/>> data Smallest a = Smallest a | PlusInfinity deriving (Show,Eq,Ord)<BR/>> data Largest a = MinusInfinity | Largest a deriving (Show,Eq,Ord)<BR/><BR/>> instance (Ord a) => Monoid (Smallest a) where<BR/>> mempty = PlusInfinity<BR/>> mappend = min<BR/><BR/>> instance (Ord a) => Monoid (Largest a) where<BR/>> mempty = MinusInfinity<BR/>> mappend = max<BR/><BR/>> ex10 = foldMap (Smallest &&& Largest) tree :: (Smallest Int,Largest Int)<BR/><BR/>And the implementation would then be just:<BR/><BR/>> ex10 = foldMap (Smallest &&& Largest) tree :: (Smallest Int,Largest Int)<BR/><BR/>I got the idea for using &&& from http://hpaste.org/14067<BR/><BR/>This is an updated version. My first attempt was wrong :-(sigfpehttps://www.blogger.com/profile/08096190433222340957noreply@blogger.com