6 ms·
As a counterpoint, I'm fluent in mathematics but know virtually no Haskell. Your write up presumes the exact opposite and is therefore totally unsuitable for s
by jfarmer 13y ago
As a counterpoint, I'm fluent in mathematics but know virtually no Haskell. Your write up presumes the exact opposite and is therefore totally unsuitable for someone like me. :)
I mean that quite literally: I can make neither heads nor tails of your write up. It looks like a bunch of text with funny characters to me. This write up, OTOH, is written in my language using idioms I understand and relates it to Haskell without involving too much of the machinery of the language.
- reeses 13y agoThis is precisely what made Haskell's monads difficult for me to understand. I kept trying to fit the square block in the round hole. I finally had to divorce the terms in my head, much like watching the film version of a book that I have read. They are..."related" but frustration will result from assuming they will be the same.
- jfarmer 13y agoNice! Yeah. I had two avenues of understanding available to me when it came to monads. The first was my knowledge as a mathematically-inclined software engineer. The second was my knowledge as someone fluent in high-level mathematics. I'll say, here was one key to my understanding once I saw it. In a purely functional language you want everything to be referentially transparent. That is, an expression should be able to be substituted for its value at any given moment in time. At the very least, you'll want the ability to denote which parts of your program are referentially transparent and which aren't. This can be expressed as utopian vision: in a purely functional language we'd like everything -- everything -- to be a value. We now need some way of translating code with side effects into code that returns a value. The logical abstraction is to say that the "value" is not the work itself -- once the work is done it's out of the bag, after all -- but rather the "value" is the machine which can perform that work. To a mathematician this screams "functor." If you want to move between the two spaces repeatedly this screams "adjoint functors." There's some work you want to do in Space A that's more easily expressed in Space B, so you take a thing in A, transform it to a thing in B, do the work in B, and then transform back to A. Think in, e.g., Ruby: sentence.split(' ').map(&:reverse).join(' ') split(' ') and join(' ') aren't quite inverses of each other, but they are adjoint. These pairs take us from the land of space-separated strings to the land of arrays back to the land of space separated strings. You see that all the time in programming and mathematics. I sometimes call it the "Super Mario Brothers" maneuver when I'm trying to teach it to students. Mario wants to get to the end of the level, so he hits a block, goes up the vine to cloud land, runs through cloud land, and then comes back down.
- minikomi 13y agoI would love to see you write more in this style - it's very clear and straight forward.
- omaranto 13y agoI disagree, I found it very muddled. For example, how are split(' ') and join(' ') supposed to be adjoint functors when they're not even functors?
- chas 13y agoHe's playing fast and loose with the formalisms to try to convey the intuition to people without a strong algebraic background. Ruby isn't very well behaved from a categorical perspective (heck, even Haskell doesn't get all of the way there if you want to be really formal) so it's not perfect, but I think the reasoning is morally correct and insightful.
- omaranto 13y agosplit(' ') and join(' ') aren't quite inverses of each other, but they are adjoint. Do you mean you think they are adjoint functors? How are they functors, between which categories?
- tel 13y agoI wouldn't say they're the tightest functors ever, but you could see them as endofunctors between the subcategories String and [String]. Some small amount of intuition would translate, although by and large this setting isn't polymorphic enough to have good behavior. After all, there are a lot of functions on strings that would not have a functorial relationship over split(' ').
- jfarmer 13y agoYes, this is more correct, and I was also imagining the category being something like "space-delimited strings." I realize that'd require redefining things like string concatenation to be "space-delimited concatenation" and other such bits. Anyhow, I was playing loose and I know it. If I were writing in a more serious context I'd cross all the t's and dot all the i's. To me the more important thing was this slow gnawing in my gut, seeing hints of natural transformations and adjoint functors here and there and thinking, "Oh come on, there has to be a way to connect these dots." Non-functional languages like Ruby don't think in this way, so there are hole all over the language.
- nilkn 13y agoPersonally, I found the Haskell in this article far harder than the math, which was more or less trivial to anyone who knows some category theory. For instance, the following newtype (FComp g f) x = FComp { unCompose :: g (f x) } instance (Functor b c f, Functor a b g) => Functor a c (FComp g f) where fmap f (FComp xs) = FComp $ fmap (fmap f) xs just does not parse easily at all to my mind. In fact, I don't see how someone who doesn't know Haskell could possibly understand the above truly. unCompose isn't even ever used.
- jfarmer 13y agoYeah, some of the syntax was confusing for me, too, but I trusted that it was equivalent to the mathematical statements. Here's the original paper on monads, which I highly recommend: http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/ba...
- comex 13y agoAnd for me, as someone experienced with programming languages but only casually poking at the math, it didn't take that long to learn Haskell's syntax, but syntax that gratuitously uses η and μ (which look vaguely like mirror images of each other) is confusing, and I expect I would have a hard time remembering which is which (of course, I would probably learn to read Greek letters instinctively after spending some time reading them). And after at least 10 minutes, I cannot figure out what "Tμ" in "μ∘Tμ" means, syntactically, while no matter how confusing the Haskell code, it can at least be parsed unambiguously. So a matter of taste!
- nilkn 13y agoIt's really not the syntax that's the issue. It's the fact that the author of the article is embedding the category-theoretic concepts into the language at the type level, so wrapper types like Id and FComp have to be introduced as "hacks" to represent functors. My main takeaway from this article is that at the end of the day Haskell is a programming language and not the most natural setting for abstract mathematics, even if there are many connections between the two areas.