Since a type being a monad just means it supports three operations (wrapping a value into the type, applying a transformation function to values “within” the type, and flattening the type when it ends up inside itself)

Quite possibly the best explanation of a monad I've seen, and it's packaged as an aside.

And his first example is quantum mechanics. Yeah, that's not abstract at all.

Well, if it's any consolation, he gets the terminology wrong...and so far as I can decipher, his quantum example isn't quite right.

His diagrams really illustrate quantum states (linear combinations of "kets") -- the notion of a "superposition" in quantum theory has to do with the linear algebraic mathematics underpinning it all.

But to say that a "quantum superposition is a lot like a probability distribution, except the probabilities are complex numbers." WRONG!

(Even the link the author gives stresses it's "probability amplitudes" which are like the "square-root" of probability, which is obtained from the inner product...not the superpositioned state.)

I think what the author is trying to get at is: a quantum observable does not form a monad on the "category of quantum states for a fixed system".

I don't know if this is true, since my good friend Jamie Vicary wrote a paper back in 2007 "A categorical framework for the quantum harmonic oscillator" arXiv:0706.0711 discussing the ladder operators forming a commutative comonoid. From there, it's an absolute triviality to induce a monad (or comonad, whichever) on some category. In the time-honored tradition of mathematical physicists, I'll leave it as an exercise to the reader.

QM as it applies to computers really is like probability over complex numbers, I just failed to make it clear to you that the mapping isn't one-to-one.

To be clear: the 1-norm is replaced by the 2-norm (you have to maintain the squared sum = 1 instead of the sum = 1), and stochastic matrices are replaced by unitary matrices. I did link to lecture notes where Scott Aaronson goes into more detail.

QM applied to anything gives you "probability amplitudes" (which are like the "square root" of probabilities). These are complex numbers who "absolute value" [i.e., modulus] squared gives you the relevant probabilities.

The remark about norms isn't relevant to the notion of probability amplitudes, really, since the Hilbert space for the quantum system always has an induced norm from the inner product. This is different than the modulus operation for probability amplitudes. (But you are very astute for catching the fact it is a norm!)

Superposition of states is the principle which means quite literally a linear combination of kets (or, dually, bras). Talking about "quantum superpositions" is meaningless, but discussing "quantum states" is meaningful, at least in particle physics. This is a critical point.

The endofunctor that's being considered acts on the "category of quantum states"...but in the paper I referred to earlier, for an infinite dimensional quantum system we get something stronger than a monad: a comonoid. After all, monads in a category C are just monoids in the category of endofunctors for that given category C.

What you are getting at appears to me something along the lines of Taking the expectation value for "sufficiently nice" observables does not form a monad on the category of "sufficiently nice" observables for a fixed quantum system. Now this is true, but it boils down to a rudimentary fact about traces of products of matrices...

The area superpositions are applied, quantum mechanics, is abstract. The superposition type itself is concrete (compared to monads).

That's what I had in mind when I said "not more abstract", anyways.

A superposition is just a dictionary of values to complex numbers, where the squared lengths add up to 100% (you can view the code on github). The fact that it applies to quantum physics is nothing but motivation to notice the type.

Matrices of a fixed shape do constitute a monad. If you can encode the shape of the matrix into the type, then you can define a monad on that type. Suppose n and m are the types of the indexes of the matrix, and that any (i, j) :: (n, m) is a valid location. Then we can encode matrices as functions of type (i, j) -> a, which is just a special case of the function/Reader monad (a representable functor):

You're flattening functions of type Point -> Point -> T, which is Func<Point, Func<Point, T>>, into (Point, Point) -> T which is Func<Tuple<Point, Point>, T>, right?

But a matrix doesn't map tuples of points to values, it maps points to values. The flattened function is not a flattened matrix. Maybe I'm just not understanding what you mean. Could you give the flatten function you're claiming works?

Interesting. That won't work in the general case I outlined, but it does work as long as the inner matrices are exactly the same size (or larger). I guess that's what you meant by "the same shape". It throws away values, but in a sort of consistent nice way.

The more general point, which may or may not be tangential to your submission (I'll let more knowledgeable people chime in) is that a Matrix type that has matrices of different shapes as members is far from an ideal use of the type system. Ideally we would want to encode the size of the matrix in the type parameters:

This assumes that all of the values in types n, m and p are valid indexes for the matrices constructed on those types. If for each natural number n we have a distinct type Range n whose elements are the numbers in the range [0 .. n-1], then that does the trick nicely.

Also, note that the type of product looks very much like the type of composition:

This is rather neat, because it's picking up some of the underlying semantics of matrices: a matrix represents a linear transformation (a function with certain properties), and the product of two matrices represents the composition of the corresponding linear transformations. There's a Category instance lurking somewhere around here with product as its (.) method (though my use of Enum in the example precludes me from writing one).

Again, this is all kind of tangential to your submission until we observe this: Matrix n m has a Monad instance. So the idea would be:

There is an argument to be made that matrix types ought to encode the matrices' shapes.

If we accept this argument, it follows that each matrix type is a monad by virtue of being isomorphic to a function type.

sqrt(2) |A> represents the same state as |A> -- so that example isn't a problem. Quantum superpositions are unchanged by scalar multiplication by nonzero constants.

The ability to get 0 is a problem however, since states are supposed to lie in a projective space.

The free vector space construction, sending a set to a (complex) vector space having that set as its basis does give a monad. However, in order to form the projective space, you need to remove 0 before quotienting out by scalar multiples.

Coordinates for quantum states don't need to have their 2-norm equal to 1. It just has to be nonzero. Coordinates which differ by a nonzero complex scalar multiple refer to the same state (thus it's always possible to make the norm equal to 1, but not necessary).

It's also worth pointing out that there are also pairs of states which are equivalent and yet both have norm 1, as you can always multiply by a complex number on the unit circle without affecting the norm.

As for the free vector space, given any set X and field F, we can form the set UVX of formal linear combinations of (finitely many) elements of X with coefficients in F. That is, the elements of UVX are functions v: X -> F where for all but finitely many x in X, v(x) = 0. The reason I'm calling this UVX is that I'm going to turn this into a vector space VX, and U will be the functor which sends each vector space to its underlying set, and each linear transformation to the underlying function.

So we can turn the set UVX into a vector space VX as follows. Addition is pointwise:

For each u and v in VX and all x in X, (u + v)(x) = u(x) + v(x).

Scalar multiplication is also pointwise:

For every u in VX, a in F and x in X, (a*u)(x) = a * (u(x)).

The vector space axioms are all easy to prove, and immediately follow from corresponding properties of F.

We can define a function:

eta_X : X -> UVX

which sends an element x of X to the function which sends x to 1, and every other element of X to 0.

An arbitrary function v in UVX can be written as a sum:

sum over x in X of v(x) * eta_X(x)

where the sum actually has finitely many terms (because by construction there are only finitely many x for which v(x) is nonzero).

Normally, applications of eta_X are left unwritten, making this look like a linear combination of some elements of X, and we just think of X as a subset of UVX (or of VX) in that way. However, this eta_X is the component at X of a natural transformation eta, which is the unit of our monad. It's also the unit of an adjunction: V is left adjoint to U. That is, linear transformations VX -> Y (where X ranges over sets, and Y ranges over vector spaces) are in natural bijection with set functions X -> UY. This fact is essentially what we use when we form a matrix representation of a linear map, capturing what it does to some basis, and recording that data in the columns of a matrix.

The counit of this adjunction is given by the linear transformations epsilon_X: VUX -> X which "evaluates" a formal linear combination of elements of a vector space X to the appropriate element of X. That is, it will send v in the vector space VUX, i.e. v: UX -> F, to the finite sum over x in UX of v(x) * x, where the latter sum and scalar multiplication are the vector space operations of X. It can be checked that this epsilon_X is really a linear transformation.

Every adjunction gives rise to a monad. The multiplication in this monad is a function mu_X: UVUVX -> UVX which takes a formal linear combination of formal linear combinations, and "distributes".

For example, if X is {a,b,c}, we might have some element of UVUVX which looks like:

{3 * {a + b + c} + 5 * {2 * a - 6 * b} + 10*{0} - 5 * {2 * c}}

That is, this is notation for a function which sends the linear combination {a + b + c} to 3, and {a + b + c} is itself notation for the function which sends each element of {a,b,c} to 1.

Finding good notation for this stuff is kind of tricky, so hopefully it makes sense what happened there. Morally, we're just removing the inner quotes and collecting like terms. It should be somewhat reminiscent of what goes on with the list monad, where we concatenate the list of lists.

So, finally, UV is a monad on the category of sets, with unit eta: 1 -> UV, and multiplication mu: UVUV -> UV. The algebras of this monad are precisely vector spaces (albeit described in a somewhat funny holistic way, where we express how to evaluate linear combinations to elements of the vector space, rather than defining a separate addition and scalar multiplication), and the algebra homomorphisms between them are precisely linear maps. If we didn't already have a notion of vector spaces, we could actually set up the monad UV in the category of sets on its own, and define abstract vector spaces in this way in terms of it.

Coordinates for quantum states don't need to have their 2-norm equal to 1.

Oh, we have something different in mind when we say state.

The use case where I ran into the type was a simple optical circuit simulator. I represented the state-of-the-world as a superposition. I did in fact have the constraint that a superposition with 2-norm not equal to 1 was malformed. When that happened, it meant I had a bug.

(Which is ultimately how I came across the example. I experimented with superpositions being a monad, in case that would make things simpler in the program, but of course found cases where it breaks the 2-norm invariant.)

Pretty much all of these examples are pointless. The quantum state example is pointless because it uses the wrong definition (cf. cgibbard's post). The matrix example is pointless because the structure of matrices is eviscerated by glomming them all together in the same set. The last example is pointless because simple types don't have the right kind to be a monad in the first place. It's like claiming an airplane isn't a banana.

In the first example, the first error is in thinking that the monad must include the base object. It doesn't: the Maybe monad is a counterexample, and the List monad deals with empty lists just fine. A second error is in thinking that because you can't use the same flattening function as the corresponding "free" monad (I use scare quotes because I'm not sure this is exactly the right term) that no function with the necessary characteristics could be written. In other words, it's fine that your invariant isn't maintained by the most obvious flattening function because you can easily fix it up afterwards.

In the second example, the error is using ill-typed matrices as a counterexample. A matrix with some matrix elements and some value elements is ill-typed. The corresponding example isn't [[A,B], [A], [C]], it's [[A,B], A, C], which is also ill-typed. Though it's true that square matrices with different sizes would not form a monad (unlike a list), as secundim mentioned.

In the third example, the Haskell crowd calls it the Writer monad (or perhaps the Cont monad. His description is vague). It's easier to point to a working example than the unpack all of the errors.

In other words, it's fine that your invariant isn't maintained by the most obvious flattening function because you can easily fix it up afterwards.

I mention in the post that I care about the flattening function being natural. If you have a quantum superposition type, and it doesn't interfere equal states by adding their amplitudes, then it doesn't follow the rules of quantum physics.

The fact that you can come up with a totally arbitrary flattening function, like just picking one of the values and giving it an amplitude of 1 and ignoring the others, is beside the point. I wanted to treat quantum superpositions like monads, exactly like I do for probability distributions, but I can't because it breaks the rules I want to follow as part of simulating a quantum system.

For example, some of the operations you can do with transform, like unconditionally transforming all the values to 0, simply don't correspond to unitary matrices. All operations on quantum states must be equivalent to multiplication by a unitary matrix. Therefore transforming must either not interfere states (which is the whole point), or must fail to maintain the 2-norm == 1 invariant I specified.

In the second example, the error is using ill-typed matrices as a counterexample. A matrix with some matrix elements and some value elements is ill-typed.

The outer matrix only contains matrices. Three 1x1 matrices containing a single item, and a 2x2 matrix containing four items. The example is well-typed.

In the third example, the Haskell crowd calls it the Writer monad

The writer monad is totally a different concept. I'm sorry I picked a confusingly similar name. The Writer monad pairs values with logging data (text), and takes care of propagating/concatenating that as you progress through a computation. The too-similarly-named Printer just prints a value. It has no concept of pairing or of progressing a computation.

The writer monad is totally a different concept. I'm sorry I picked a confusingly similar name. The Writer monad pairs values with logging data (text), and takes care of propagating/concatenating that as you progress through a computation. The too-similarly-named Printer just prints a value. It has no concept of pairing or of progressing a computation.

Then how it is a type constructor? What's the difference between Printer(Int) and Printer(String). I think you don't have in mind a lot that a monad must be a type constructor, not a type: you made the same kind of failure in other articles.

I think you just didn't define it well: specially because your definition of "parser" and "printer" sound like the same thing. As I see it, you could mean:

newtype Printer input output = Printer (input -> output)

In which case it's the Reader monad.

It could also be:

newtype Printer input a = Printer (input -> (IO (), a))

In which case it's the Writer monad.

It could also be this:

newtype Printer input a = Printer (input -> IO ())

In this case, it's Const. In this case, you're right: it isn't a monad.

Hold on: you mean that your wrap is of type input -> Printer a or input -> Printer input.

It it's the first, your function isn't "wrap". If it's the second, you're right that it doesn't form a monad. If you want to know it, it's because something more profound that flatten or wrap. It's because it doesn't form a covariant functor, but a contravariant one(that means, fmap :: (a -> b) -> Printer a -> Printer b doesn't exist, but contrafmap :: (a -> b) -> Printer b -> Printer a does). I'm not sure if flatten and wrap can be implemented, but if they can be, they are kinda useless, because you can't implement bind, or equivalently, can't compose Kleisly arrows, so it's not a monad.

If it's the second, you're right that it doesn't form a monad. If you want to know it, it's because something more profound that flatten or wrap. It's because it doesn't form a covariant functor, but a contravariant one

It's just that the definition of Monad fits onto three lines, literally, and any attempt to explain them in a few hundred lines of prose is basically bound to fail, because there's any number of ways to screw up in those hundreds of lines and glom on to the wrong conceptual framework. It's not that they're too complicated to explain... it's that they're too simple to explain. No sarcasm. People keep thinking "Monad" is this mystic magic thing, but it's just a very small interface that happens to be very powerful.

It's like thinking Iterators are this magical wonderful thing, because look, I can implement an iterator on a Hash and a List and a Red-Black tree and on a web page and an XML document and a set and a string and HOLY SHIT iterators are complicated man it's like trying to swallow an entire Data Structures textbook to understand them AAAAAAAA!

But that's not true. An iterator is an interface where you have a "next" method and some way of telling you're done. That's all. The staggering array of implementations of Iterator are consequences of applying iterators in some specific domain, and range from something as mundane as iterating over a list to something as weird as iterating over all possible states in some game's state space... but the weird iterators are because you're doing weird things with them, not because Iterator is weird. Monad is slightly more complicated than Iterator, but only slightly. It's just complicated in a direction people aren't used to thinking about.

Because so many common types are monads, they can all be worked with in the same way. Your experience using map on List applies directly to realizing how then works on futures, etc.

Languages can include syntax to make working with monads easier. Haskell has 'do' notation, C# has linq, F# has computation expressions, etc. The benefits of this syntax are not huge, but they apply very, very widely.

You can write methods that work with arbitrary monads, just like you can write methods that work with arbitrary collections or enumerables.

In how would I even use a monad? I give a practical example of a method based on monads. In the post I wrote it in pseudo-C#, but here it is in Haskell along with code to print it:

Take a look at the Maybe monad. It wraps a value (like an int), so that you can still perform int-like operations on it, treat it like an int. However,it captures an additional state of "not set" or "undefined".

Internally, the Maybe monad decides to ignore any transform operations if the value is undefined. I think I've shown the "wrap" and "transform" bits there, but anyone else care to show where "flatten" comes into play for Maybe?

I started out fairly sure I could give an example, but dammit.. monads.

Monad tutorials might well be the equivalent of Mornington Crescent - the game. But monads themselves are more like Mornington Crescent the tube station: a perfectly normal useful thing, one that gets talked about all out of proportion to its importance.