Hacker News new | past | comments | ask | show | jobs | submit login

Functors are containers that can apply a function ("fmap") to their contents. (...) Monoids are even more generic -- they are something that has an "identity" and an "append" operation.

Argh! Pet peeve time. Functors are not containers and calling them that makes it harder to understand how something like IO, ((->) a), or a Parsec parser qualify; also, some container types aren't (and can't be) Functors because they aren't polymorphic in the contained type (IntSet or ByteString, for instance).

Likewise, calling the Monoid operation "append" is needlessly confusing (and yes, the names the standard library uses are terrible). It's an associative binary operation with an identity value and no semantics whatsoever beyond that. Appending data structures is likely to form a monoid, but so can merging them (union and intersection both work). Any instance of Ord forms monoids under min and max. Functions are a monoid under composition. Even () forms a (trivial) monoid.

I'm pretty sure none of that is news to you, but I think using descriptions like "container" and "append" invoke too many preconceived ideas for people new to Haskell and creates barriers to understanding more than it helps. Most of this stuff is actually quite simple, but it's almost painfully abstract, and using concrete metaphors of familiar things obscures the full generality.

It's particularly a problem with Monoid, because the concept is both utterly trivial and broadly useful, but calling it "append" leads to people complaining about Haskell using a needlessly cryptic term for "appendable things" while simultaneously missing the entire point of the type class.

So anyway, just start programming, and you'll see why these abstractions are useful. You'll also see why "easy to understand" abstractions like "foldable" and "traversable" are useful too, even though there is not much category theory there.

For what it's worth, from a mathy perspective, I think Traversable represents some sort of distributive law between Functors (e.g., lets you do something that looks like "f (g a) -> g (f a)").

In categorical terms Foldable is related to "catamorphisms", though to my understanding the relevant bits of category theory were first explored by, and remain of interest mostly to, programming language theorists. Look at http://knol.google.com/k/edward-kmett/catamorphisms if you're brave enough...




You're right that calling a functor a container is an oversimplification. But when you start explaining something at full generality, it only makes sense to people that already understand the full generality. Once you understand how List and Tree are similar, you can understand how List, Tree, Reader, and IO are similar. But if you don't see any connections between List and Tree, you are never going to see any connection between List and IO. So, you need to simplify, understand the simplification, and then try to attack full generality.

The same goes for monoids. Many people won't see any use for "identity + associative binary operator". But they will understand the similarities between "append to a list" and "add numbers". Once you see something concrete, then you can worry about abstraction. If you don't understand the concrete, though, you aren't going to get there from the abstraction.

(Nobody ever said, "I'll define a functor to be ... Now I'll write a program with this functor!" Instead, they noticed how lists and trees were similar, and invented the functor abstraction afterwards. If you learn and discover things the same way they did, you'll eventually have the same deep understanding they do. That understanding is what allows you to use the abstractions, not the definition you find in a textbook.)

So anyway, if you are teaching people Haskell, it's better to teach them the concrete. Once they understand that, you can amend the definition to be fully abstract. Then they will be comfortable with the abstraction and its applications.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: