Skip to content

Instantly share code, notes, and snippets.

@nugend
Last active August 29, 2015 14:01
Show Gist options
  • Save nugend/37030bd92ecec003c5af to your computer and use it in GitHub Desktop.
Save nugend/37030bd92ecec003c5af to your computer and use it in GitHub Desktop.
What does "Monad" mean?

Monads are complicated because the word "monad" bears too much weight in any discussion about them.

  1. There is a category theoretical concept of a monad. This is largely irrelevant in a practical explanation of monads since Monads are usually talked about in terms of another category theoretical concept called the Kleisli Category or Kleisli Triple. However, if someone starts talking about "monad laws", they're probably referring to the theoretical sense of this.

  2. There is, in Haskell at any rate, a typeclass called the Monad (note the capital "M"). This is mostly important because when a type is an instance of this category, the Haskell do-notation is useful. Aside from that, you can only use the handful of operations that the Monad typeclass implements that you don't have to implement yourself for it to be an instance of Monad.

  3. There are Monad type constructors, such as Maybe, IO, and State. This is where things actually start getting interesting for the practitioner, because each provides a specific abstraction of a concept, such as input/output or partial functions (IO and Maybe, respectively).

  4. There are Monad types, both abstract and concrete, like Maybe a, IO a, Maybe Int, State MyType and so on. These are the types you actually will program with.

  5. There are Monad values, which are instances of the Monad types, which are, themselves, instances of the Monad type constructors, which are instances of the Monad typeclass.

  6. Then just to add a slightly extra confusing layer on top of it all, you have the values inside the Monad you'll actually be doing computations with.

  7. And finally, it doesn't help when in code examples, type variables and function variables are conflated by name, such as in:

    get :: State s s
    get s = (s,s)

Unfortunately, that's much more clear for an expert than a beginner in regards to what's going on there, so if you're reading code samples, likely written by people with expertise, they're going to be confusing. So, yeah. Simple concept of explicit effects. Seriously semantically overloaded stack of terms to actual reason with them about.

Minor nitpicks:

"Monadic types" and "Monadic values" would be better for 4 and 5, because "Monad types" are the type constructors (which are also sometimes named types). And "monad values" is not a term I've ever heard used.

Also, values have-type, they're not instance-of. So it would be slightly more accurate to say monadic values are values of a monadic type, whose type constructor is an instance of the Monad type-class.

I agree better and more accurate use of accepted terminology for all these concepts could be useful.

As for the namespacing issue in the examples, it might be confusing for a complete beginner, but one of the first things you learn in Haskell (ideally before Monads) is how scoping works.

I'm sure I've made some terminology decisions that are questionable, but in light of someone writing the community approved guide to talking about monads, I'll try to explain what I was trying to get across.

First, I was trying to emphasize that a type constructor is not strictly a type in the sense of a value having a type. While we commonly speak about to the parameterized types without their type arguments, they aren't really "types" in the type theory sense while there are still type arguments to be supplied. That is, Maybe's kind is * -> * while Maybe a's kind is * even though a is a generic type.

When referring to something as a "monadic value" I was just trying to emphasize that the monad that contains a value is itself a value in the Haskell runtime system and that such a "monadic value" is separate from the value contained there within.

Finally, maybe this is a bad habit of mine, but I've always referred to values as instances since they inhabit types.

I disagree that the namespacing is only ever an issue for a complete beginner. The visual separation between a type expression and a value expression in Haskell can be pretty thin. It's not just about whether they are unambiguous but how much attention you have to pay to while you're skimming code. Honestly, I don't think there's much that can be done about it, but it's just the cherry on top for beginner and intermediate users. Especially ones who aren't using Haskell regularly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment