tag:blogger.com,1999:blog-1777990983847811806.post171760268230001678..comments2017-06-23T20:26:41.995-07:00Comments on Haskell for all: The category design patternGabriel Gonzaleznoreply@blogger.comBlogger28125tag:blogger.com,1999:blog-1777990983847811806.post-5956372187928208632016-04-24T18:01:30.620-07:002016-04-24T18:01:30.620-07:00I eventually plan on writing a book, but that is s...I eventually plan on writing a book, but that is still a couple of years away before I will begin writing in earnestGabriel Gonzalezhttp://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-30686415410157778352016-04-16T08:55:22.118-07:002016-04-16T08:55:22.118-07:00Are you planning on writing them? These two posts ...Are you planning on writing them? These two posts were very insightful and I'm looking forward to the rest of them.Sushant Khadehttp://www.blogger.com/profile/13710708562223048883noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-31809487742373948512016-04-15T21:10:16.376-07:002016-04-15T21:10:16.376-07:00The functor design pattern was the only follow-up ...The functor design pattern was the only follow-up post I wrote. I haven't gotten around to writing the other posts, yetGabriel Gonzalezhttp://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-31718700544619580062016-04-14T20:54:23.157-07:002016-04-14T20:54:23.157-07:00This is truly an awesome post!
In the end you'...This is truly an awesome post!<br />In the end you've mentioned a few follow up posts. Can you point me to those? So far I've only found 'Functor Design Pattern'.Sushant Khadehttp://www.blogger.com/profile/13710708562223048883noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-66603140465566890212015-11-13T19:56:46.387-08:002015-11-13T19:56:46.387-08:00Yes. The monad laws follow exactly from the desir...Yes. The monad laws follow exactly from the desire to ensure that monadic function composition is associative and has an identityGabriel Gonzalezhttp://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-53824594684998888622015-11-13T10:51:47.522-08:002015-11-13T10:51:47.522-08:00Awesome post. To me, this explains the monad laws...Awesome post. To me, this explains the monad laws: they arise naturally if you want to define a category where monadic functions compose. Is that fair to say?Juan Pablohttp://www.blogger.com/profile/10543050127702875378noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-81992555094789280732015-11-08T15:23:56.188-08:002015-11-08T15:23:56.188-08:00As a matter of fact, there is a scripting library ...As a matter of fact, there is a scripting library I wrote which is specifically geared towards people who have no prior Haskell knowledge. You can begin from the tutorial here:<br /><br />http://hackage.haskell.org/package/turtle-1.2.2/docs/Turtle-Tutorial.html<br /><br />That's a very easy way to write something useful in Haskell without a huge upfront investment.Gabriel Gonzalezhttp://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-18661231061277047602015-11-08T15:07:46.284-08:002015-11-08T15:07:46.284-08:00Great post. I really love math and especially cate...Great post. I really love math and especially category theory, so to see it applied to Haskell means I'm immediately going to take another look at the language. Just a question though. I really want to learn haskell but the Rubyist in me just finds it easier to bang out a quick script when I need something. Is there any like things I can do with Haskell while I'm learning? Like I find it helpful to learn by building so any ideas. Thanks and awesome post.Unknownhttp://www.blogger.com/profile/01756124415478025126noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-20602181034681638562012-10-27T07:44:16.240-07:002012-10-27T07:44:16.240-07:00You are correct. The a and b are the objects and ...You are correct. The a and b are the objects and they are Haskell types. So, interestingly, when you generalize pipes to proxies then you get two extra categories (see the Interact class in Control.Proxy.Class) and they do make use of the r parameter.Gabriel Gonzalezhttp://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-82990345512469828912012-10-27T05:23:43.428-07:002012-10-27T05:23:43.428-07:00So, what *are* the objects for the Pipe category? ...So, what *are* the objects for the Pipe category? Are they Haskell types, just like in Hask? Are the objects on either side of the Pipe morphism represented by 'a' and 'b' in "Pipe a b r"? and if so, what does 'r' represent? If not, how far off the mark am I, exactly? :)Bryan Richterhttp://www.blogger.com/profile/00380593834900043397noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-78580732980534280482012-10-22T10:20:59.437-07:002012-10-22T10:20:59.437-07:00Thanks for the kind words! I've actually been...Thanks for the kind words! I've actually been learning from Awodey's book since I don't have a very strong mathematical background for MacLane's book, yet, but I plan to work through it eventually.<br /><br />I was plan on doing a follow-up post discussing objects (mainly in the context of Haskell types). Even in my own code with long composition chains, I often annotate the type of each intermediate step as a comment to help keep track of what is going on.Gabriel Gonzalezhttp://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-79577427174884343682012-10-19T02:31:43.938-07:002012-10-19T02:31:43.938-07:00oops, speaking of noncommutativity, that's &qu...oops, speaking of noncommutativity, that's "Saunders MacLane", of course!stephen@xemacshttp://www.blogger.com/profile/02458669418391940756noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-90175223232161968222012-10-19T02:28:24.928-07:002012-10-19T02:28:24.928-07:00By the way, talking about "order of grouping&...By the way, talking about "order of grouping" is a little awkward (composition is generally not commutative). I think if you rephrase to something like "nesting of groups" the flow will be more natural for the reader.stephen@xemacshttp://www.blogger.com/profile/02458669418391940756noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-37706619069181349602012-10-19T02:25:21.481-07:002012-10-19T02:25:21.481-07:00You don't really need to apologize. Saying th...You don't really need to apologize. Saying the "category of X" where X is the objects is a trope. (Consider the usual description of a monoid as a category: how many monoids can be defined on a given set? All of them, and you don't even need any elements in the set as long as you don't ask that the arrows be functions!) OTOH, if you have the morphisms, then (via the source and target maps of the identities) you have the objects.<br /><br />As MacLane Saunders points out, it takes courage to name your categories by the common names of their arrows, rather than by the common names of their objects. I honor your bravery!<br /><br />Your point about "what the programmer works with" is well-taken, except that one reason why so many programmers don't get functional programming (at least at first) is because they want to work with objects. What you could say here is something like "the morphisms are what you work with if you want to achieve elegant, compact programs expressing complex relationships."stephen@xemacshttp://www.blogger.com/profile/02458669418391940756noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-16874072148768450092012-08-22T07:17:25.674-07:002012-08-22T07:17:25.674-07:00Thank you very much! I understand enough French t...Thank you very much! I understand enough French to know you did an excellent job of translation.Gabriel Gonzalezhttp://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-66457705459858156412012-08-22T06:54:15.988-07:002012-08-22T06:54:15.988-07:00done at http://blog.demotera.com/published/2012-08...done at http://blog.demotera.com/published/2012-08-22-Programmation-Fonctionnelle-et-Theorie-des-Categories.htmlPaulhttp://www.blogger.com/profile/04809113583211386483noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-77647233203318368012012-08-21T07:04:17.601-07:002012-08-21T07:04:17.601-07:00That sounds great! I really appreciate it.That sounds great! I really appreciate it.Gabriel Gonzalezhttp://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-14327434939571480002012-08-21T02:29:11.854-07:002012-08-21T02:29:11.854-07:00Hi Gabriel, nice post.
I was planning to write so...Hi Gabriel, nice post.<br /><br />I was planning to write something on the same topic, but in french, sometime in the near future. Haskell documentation is lacking in this dialect, and I hope that adding more content will create more opportunities for people to get into the purely functional way of programming.<br /><br />If you agree, I could also translate this good article, and credit it clearly of course. What do you think about that ?Paulhttp://www.blogger.com/profile/04809113583211386483noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-42378143318825945422012-08-19T12:43:44.625-07:002012-08-19T12:43:44.625-07:00Sorry, I made a mistake (read your reply too quick...Sorry, I made a mistake (read your reply too quickly), of course you can say 7 = id 7 because this is just 7 = 7.<br /><br />Well, at least from my way of thinking, you have two equalities:<br /><br />idP = Await (\a -> Yield a idP)<br /><br />and<br /><br />idP <+< idP = Await (\a -> Yield a (idP <+< idP))<br /><br />These are sort of "clearly" the same under a renaming. It may be true that you need deeper aspects of coinduction to prove it, but I'm not a good enough theorist to know :). sayntehttp://www.blogger.com/profile/09919237195037728981noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-57711118108619463412012-08-19T10:27:54.570-07:002012-08-19T10:27:54.570-07:00The correction is appreciated. If I didn't en...The correction is appreciated. If I didn't enjoy being corrected I wouldn't be programming in Haskell in the first place!<br /><br />I suppose there needs to be a better word for describing the "the category whose morphisms are X" because I agree that the way I phrased it bastardizes the terminology. From my perspective, what the programmer sees and works with are the morphisms, which is why I try to present categories in terms of the morphisms. Obviously the objects in the category affect which morphisms are compatible for composition, and I see that as being the second step of the presentation, not the first. I have to lead with the motivation (i.e. composition) otherwise it will read like every other category theory introduction which presents a bunch of rules and formalisms with no discussion of why we even need category theory in the first place.<br /><br />I tried to make it clear that each monad generates its own Kleisli category, but in retrospect I see that I described it the wrong way. I need to think about how to word it better so that the description still flows.Gabriel Gonzalezhttp://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-21545360253324414312012-08-19T09:42:37.153-07:002012-08-19T09:42:37.153-07:00OK, let me see if I've got this straight.
From...OK, let me see if I've got this straight.<br />From the *definition*<br /><br /> foo = id foo<br /><br />I can conclude that foo is the *least* (well-defined) fixed point of id, i.e. bottom.<br /><br />From the mere (easy to prove) equality <br /><br /> 7 = id 7<br /><br />I can only conclude that 7 is *some* fixed point of id, not that 7 = foo.<br /><br />Similarly, from the definition<br /><br /> idP = Await (\a -> Yield a idP)<br /><br />I can conclude that idP is the least well-defined fixed point of the function G = \f -> Await (\a -> Yield a f),<br />whereas from the mere equality (not definition)<br /><br /> idP <+< idP = Await (\a -> Yield a (idP <+< idP))<br /><br />I can only conclude that idP <+< idP is *some* fixed point of G, not (without more) that idP <+< idP = idP.<br /><br />The missing piece might be that there is only one fixed point of G. That seems plausible to me, although right now I'm not sure how to prove it. It might be related to Gabriel's comment about bisimulation and coinduction.myzoskihttp://www.blogger.com/profile/02622704681931775367noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-79731452224777064552012-08-18T22:27:31.456-07:002012-08-18T22:27:31.456-07:00Well, remember that here you are *defining* (for e...Well, remember that here you are *defining* (for example):<br /><br />foo = id foo<br /><br />that's what foo *means*. You cannot say that 7 = id 7 because 7 *means* something else: it has another definition. The previous was fine because I was picking a fresh name (for example "f") that had no previous definition. <br /><br />The substitution was actually just to show you that your proof worked because your equality had the right 'structure', not because you already knew that "idP <+< idP = idP".<br /><br />I hope that helps!sayntehttp://www.blogger.com/profile/09919237195037728981noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-61457432807267764832012-08-18T21:42:54.492-07:002012-08-18T21:42:54.492-07:00I hate to be the snooty mathematician who corrects...I hate to be the snooty mathematician who corrects terminology, but here goes.<br /><br />When you say something is the "category of X" you really mean the objects in that category are X and you have to define the morphisms separately. For instance, your first category of Haskell functions is actually (probably) the category of Haskell types, and you defined the morphisms to be Haskell functions. If your category was really the category of Haskell functions, then your morphisms would need to be morphisms of Haskell functions.<br /><br />Of course, with the right tinkering you can blur the distinction between an object and the identity morphism on that object, but then the objects are still not *all* morphisms.<br /><br />Another thing to note is that the Kleisli category is defined per monad. So it's not the category of all monadic functions across all possible monads.<br /><br />I like the explanations though! I need to get back into Haskell myself.j2kunhttp://www.blogger.com/profile/08041921049916424212noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-70632842577106844382012-08-18T17:35:04.092-07:002012-08-18T17:35:04.092-07:00This comment has been removed by the author.myzoskihttp://www.blogger.com/profile/02622704681931775367noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-33341082602703549092012-08-18T17:23:03.572-07:002012-08-18T17:23:03.572-07:00Hi Saynte,
Thanks! I think you are right, but I wa...Hi Saynte,<br />Thanks! I think you are right, but I was wondering if I can always conclude from<br /><br /> f = G f<br />and g = G g<br /><br />that f = g. It's certainly not always true -- for instance<br />if I make the _definition_<br /><br />foo :: a<br />foo = id foo<br /><br />then I have defined foo to be bottom; but I can't conclude<br />from the fact that<br /><br />7 = id 7<br /><br />that 7 = foo.<br />myzoskihttp://www.blogger.com/profile/02622704681931775367noreply@blogger.com