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

You shouldn't lose the ability to explain something when you understand it. There are things which require a significant amount of background knowledge to thoroughly understand, but that's a separate issue of retaining the ability to explain what they mean as you ascend the ladder of abstraction.

For example: I can say that a monad is an endofunctor which has been equipped with two structure-preserving transformations. This is correct, succinct and utterly tonedeaf unless I know that my audience has familiarity with the mathematical concepts of algebraic structures, categories of structures, the meaning of a functor, the meaning of an endofunctor, the meaning of a transformation and the meaning of "structure-preserving."

By being a little less terse I can provide a useful definition which is vastly more accessible. Start with the basics. A set A = {a, b, c} is a collection of objects. A function f: A --> B is a rule that sends one element a in set A to one element b in set B. Then we write f(a) = b, which is familiar from high school algebra. A set can consist of any kind of mathematical object - integers, rationals, reals, other sets, polynomials or even functions. Whatever you'd like.[1] Now we'll say a category is a collection of sets alongside all the functions that we can define on each pair of sets.

So let's take a category consisting of all possible sets of integers and all the possible functions that can be defined on any two of those sets of integers. Naively we can think of this category as a set of all sets of integers. Then the analogue of functions defined on sets is functors defined between categories. When dealing with functions, we can define a function on a single set so that f: A --> A means every element a of A is associated with another element of A. We can also do this with categories; this is called an endofunctor, and it essentially means it will send each object of our category to another object in the category. One way I could do this is by defining a relation that takes each set of positive integers in the category of integers and sends it to the exact same set consisting of negative integers. Each set {1, 2, 3, ...} will be sent to a set {-1, -2, -3, ...}; moreover, a function relating the set {a, b, c} and the set {x, y, z} will have a corresponding function relating the set {-a, -b, -c} to the set {-x, -y, -z} in on the other end of our functor.

So to recap, we have a category which consists of all possible sets of integers, and we've defined an endofunctor which maps any single object (set) in the category to another set within the same category - a functor defined on the category itself. Moreover, this endofunctor preserves relationships between respective sets at the function level. Now a natural transformation is a relationship between two different functors so that all the relationships that exist under the first functor also exist under the second functor. So with our current endofunctor, we might augment it with a natural transformation that transitions this functor from sets of integers to groups of integers, or rings of integers, or vector spaces of integers, etc. The respective definitions of those algebraic structures aren't germane to this explanation; basically what we're after here is the idea that we can take a functor between two like sets of elements in the same category of sets of elements and manipulate it so that if a in {a, b, c} relates to -a in {-a, -b, -c} in the same category, a will still relate to -a (and other relations on either side of the functor) after we've changed the functor to mean something slightly different.

Putting this all together: a monad a functor that sends every set in a category to another set within the same category and which has two natural transformations that "preserve" the relationships of the functor. What I've just explained is the mathematical sense of the word; the reason why this terminology is used in a language like Haskell is because it describes a very neat, abstract way of transforming one class of objects (e.g. strings) into another class of objects (e.g. integers). If we define a function for transforming any string into an integer and then we define two more functions for manipulating that function without invalidating its output, we have a functional monad. In functional programming this can be useful when we want to abstract away and compose functionality together.

Note that I'm not saying my explanation is perfect. It's greatly simplified. But it explains all the core concepts involved in the definition of a monad and it mostly does so from scratch.

_______________________

1. ...for this exercise. Please resist the temptation to bring up Russell's Paradox and ZFC.




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: