3 ms·
> A monad is a data type (e.g. int) that encapsulates some control flow (e.g. try/catch). Ignoring the fact that `int` itself doesn't have much to do with mona
by maxdamantus 7y ago
> A monad is a data type (e.g. int) that encapsulates some control flow (e.g. try/catch).
Ignoring the fact that `int` itself doesn't have much to do with monads (it's presumably just giving an example of a type), I've always disliked the notion of talking about monads being types or vice versa.
The way I think of it is that the monad itself consists of the monadic operations for some set of values. The "IO monad" consists of the `bind` and `unit` functions to do with values of types `IO<T>` for any `T` (eg, `IO<Int>`, `IO<String>`, `IO<IO<Int>>`). Similarly, the "Maybe monad" consists of the `bind` and `unit` functions to do with values of types `Maybe<T>` for any `T`.
Both of these monads can be said to implement a common interface, which might be expressed using the following Java-like code (using Java just to emphasise that there isn't really[0] anything magical here):
interface Monad<M> {
<T> M<T> unit(T v);
<T, U> M<U> bind(M<T> a, Function<T, M<U>> f);
}
If we were to define an "IO monad", we would expect it to implement `Monad<IO>`, therefore an "IO monad" is really just a value of type `Monad<IO>`:
Monad<IO> ioMonad = new Monad<IO>() {
<T> IO<T> unit(T v) { .. }
<T, U> IO<U> bind(IO<T> a, Function<T, IO<U>> f) { .. }
};
This is actually pretty much exactly how it works in Idris for example, where `Monad IO` is itself a type, and you can actually ask for the `Monad IO` implementation by writing, funnily enough, `the (Monad IO) %implementation`:
Idris> 4 + 5 -- to demonstrate the REPL
9 : Integer
Idris> Monad IO
Monad (IO' (MkFFI C_Types String String)) : Type
Idris> the (Monad IO) %implementation
constructor of Prelude.Monad.Monad (\meth, meth, meth, meth => io_bind meth meth) (\meth, meth => io_bind meth id) : Monad IO
[0] The only reason it doesn't actually work is because Java doesn't support higher-kinded polymorphism, so you can't pass type-level functions such as `IO` or `List` as type parameters, therefore you can't actually write `M<T>` as appears in the interface body.