3 ms·
First, a clarification: when looking at a monadic action `f : A -> T(B)`, the monad here is just `T`. The action itself is still just a function. The monad `T`
by Twisol 7y ago
First, a clarification: when looking at a monadic action `f : A -> T(B)`, the monad here is just `T`. The action itself is still just a function. The monad `T` lets you add some extra structure onto your usual output type in a principled way.
That being said, it's true that I'm using `T` itself in a function-like way. Category theory does blur the lines between the two ideas: monads are "functors" with some extra structure, and functors are ("just") functions between categories that preserve categorical structure. But it's critical to notice here (and it's apparent from the type `f : A -> T(B)`) that `T` is not the same kind of function that `f` is. `f` lets you move from one type to another, by mapping each value in one to a value of another. `T` lets you move from a whole category to another category, by mapping each object/type in one to an object/type of another, and mapping each arrow/function in one to an arrow/function of another.
In other words, monads occur at the type level, whereas functions occur at the value level [1]. That means that, colloquially, you can't just use a monad "instead of" a function, any more than you can use "Integer" instead of "42". But as I alluded to above, monads over partial orders are closure operators, and we can often model the evolution of data over time as a partial order. So in that domain, monads literally are functions, and the "side effect" of a closure operator is mutably updating a cell by moving its contents up in the order.
If you model the evolution of data as a partial order, you can indeed obtain monads that more closely resemble normal functions. But a partial order is just a particular kind of category, so even here we've built a separate little domain over which our monad exists. (Of course, functors are all about crossing those domains in principled ways.)
[1] That's why it's not "IO ()" or "Maybe Int" that are monads; it's "IO" and "Maybe" themselves, which are well-behaved functions from types to types.