Yes, the page is located at "monads.php". PHP! :P I spent very, very little time creating this website, and someday it will be running a web server written in Haskell, serving .lhs files as beautiful HTML, and all that good stuff. Someday. For now I just use some quick-n-dirty PHP to slap the simple header and footer around a plain old HTML page.

And yes, this is another Monad tutorial; but I think you'll like it. Please give it a glance, and let me know if anything:

Thanks for putting this break down in one place. When learning this material for the first time it had to be scraped from several locations. I do not think i have run into a document which covers this issues in a concise manner. Do not listen to this people calling for more examples. While examples are great many monad tutorials out there do not provide a coherent abstract structure to tie everything together. While this does.

text-align: justify is usually detrimental to readability (it makes it harder to find the next line if lines get long). Browsers are also usually don't know how to break up words, so they introduce huge spaces which hurts readability even more.

Even though my site has basically no content, I try for a minimalist layout that still looks good on mobile devices, and in the absence of other css, the headers were getting justified, which looks a bit wonky on my phone. The 10% padding works great everywhere. Someday I'll probably redo the entire site's look, but for now that little tip worked wonders. :)

Any other css tips? Not guaranteeing that I'd implement them, but I'm always open to suggestions.

I guess a white background is fine. You can always dabble in a bit of very light colour shades. Ie, light grey background, then everything inside a content div with a white background. Just don't overdo it and end up with something ugly.

Also, get your headers sorted out (this will force you to write standards compliant html, plus it looks more professional),

Well, I took the complete opposite approach. :) I feel that monad tutorials get convoluted and confusing when you try to mix up explaining "what is a monad?" with "how do I use monads?" and "why should I use monads?"

The biggest problem is that you can't show how to use a monad without showing what a monad is, and you can't show what a monad is (in a way that the average programmer understands) before you show how to use it.

you can't show what a monad is (in a way that the average programmer understands) before you show how to use it

Well this is exactly what I tried to do. If the "average programmer" doesn't understand, then, well, so be it. However, I am seriously considering writing companion tutorials that demonstrate "how to use monads". I don't believe that anyone is going to click through the link with 0% knowledge of monads, and after reading the article be 100% comfortable with monads, but I think it is a step in the right direction.

I would advise against describing monads as pointed. A point is a distinguished element, like the XPlus type classes have -- list has [], nat has 0, etc. A monad instead has an injection that will inject any value into the monad. This is a very different thing. The only way it could be true to describe a monad as pointed is if you talk about the category of endofunctors, where the injection is a natural transformation return : 1 -> m, in which case it's only pointed-al (since monads are monoidal, not true monoids).

Can you expand on this? Is it a claim about mathematical monads or just Haskell monads? What does "monoidal" mean when used like this? I thought that monoidal categories were those with a chosen bifunctor and 1 object, and monoids were objects in monoidal categories with particular homs and commutative diagrams. And monads are just monoids in the monoidal category of endofunctors over a given category.

A monoid, in the strictest sense, is a set A with two arrows e : 1 -> A, m : A*A -> A satisfying certain laws (where * is cartesian product). A monoidal object A looks pretty much the same, except it's not a set, and we use a more general notion of product. For endofunctors, the "product" is horizontal composition, so a monoidal endofunctor is an object F in the category of endofunctors for your chosen base category, with arrows (ie natural transformations) e : 1 -> F, and m : FF -> F, where adjacency is composition. Usually people will just describe monoidal objects as monoids but the distinction is pretty important because the category of monoids, for instance, is monoidal sets, not monoidal-objects-in-general.

You can keep the pointed explanation, but you should couch it in an explanation that it's a point in a particular category. As it stands, an (family of) arrow(s) return : forall a. a -> m a is not technically a point, nor even a point-oid, in the category of interest.

For a moment I was hoping you were going for the minimal approach with fmap, pure, and join. As it is the tutorial gives the impression that you have to have all these other things as well to be a monad.

Sorry to disappoint. The only "other" things I mentioned were bind and ap, (and that >=> can be derived). I did exlicitly mention that the minimal definition of a monad is either {fmap, return, and join} or {return and bind}.

I also felt it important to explain that Monad is a typeclass, where the types have kind star-to-star; it seems to me that most monad explanations take this information for granted.

But I don't think I mentioned any part of a Monad that is not a necessary part. Monads (in theory) must be Applicative Functors, which must be Functors, and also Pointed, which must have kind star-to-star.

I just started learning Haskell (using the Write yourself a Scheme in 48 hours)

I know Scala (3 year usage)

I think I understand currying from Scala and even how to use it (the Ahhh moment occured a week ago when I saw currying in Haskell).

I already understand a bit how to use monads (from the "WYS48H"). I didn't finish it yet dough.

Yet you lost me right at the beginning.

The reason is the usage of the typeclass word in:

Monad is a typeclass.

Functor is a typeclass.

Pointed is a typeclass.

Applicative is a typeclass, whose types are both Pointed and Functors.

Only later do I found out that maybe I should read typeclassopedia to understand typeclasses.

The point is that, either you leave the word "typeclass" out or you define it properly. The way it is, it is hard for your target audience since a new concept used in your Monad tutorial isn't explained anywhere.

What is a typeclass? A typeclass is a Haskell way of dealing with the following situation: suppose that you are writing a library of useful functions and you don't know in advance how exactly they will be used, so you want to make them generic. Now, on one hand you don't want to restrict your users to certain type (e.g. String). On the other hand, you want to enforce the convention that arguments for your function must satisfy a certain set of constraints. That is where typeclass comes in handy.

Think of typeclass as a contract (or "interface", in Java terms) that your type must fulfill in order to be admitted as an argument to certain functions.

As I said, I'm trying to understand the concept as we speak. So take my suggestion with LOTS of grains of salt.

Type classes are a fairly basic Haskell feature which, in a broader Haskell tutorial, would typically be covered before monads. For example in the Gentle Intro, type classes are in section 5 and monads are in section 9. Or, in RWH, Using Typeclasses is chapter 6, and Monads is chapter 14.

One of the perils of learning by blog post is that there's no such overall organization, so you have to get that guidance from somewhere else.

I'm actually not learning from blog post, this was a reddit related deviation. :)

I started Haskell with Write Yourself a Scheme in 48 Hours to get an hands on feel of what programming in Haskell really is. Then I was intending to go with the Real World Haskell book that a friend of mine pointed me to.

Real World Haskell is much more recent and has a more pragmatic emphasis, so is probably a good next step. The pace can be a little slow depending on where you're at in the learning curve, but you can always skim & skip.

Gentle Intro is pretty old (circa 2000), and has often been accused of not being at all gentle. Because of its age, it covers basic Haskell 98, with no references to newer libraries and idioms that have since become standard. As a tutorial for that core language, I think one virtue it has is that it's fairly concise, but that also makes it quite dense, hence the ungentle reputation. Whether you find it useful may depend on your learning style.

Edit: Learn You A Haskell may also be worth a look - it's lighter than RWH, and could act as a good overview/intro.

this is good stuff. i wish had read this before all the other tutorials had confused the hell out of me. question: could someone explain the difference between a "type" and a "kind" for me? they both look like function signaures to me.

The typing colon is a relation relating values to types. Nothing says that all types are inhabited. All values have types, and all types have kinds. Not all types have values, and not all kinds have types.

I think the distinction we need to make here is what people call a "sort" in Agda, which is what we allow to be on the right of a colon. Typically, people only allow "typey" things to be there, so * in Haskell, and in Agda things like Set or Set 1. You can't define new sorts in Agda, but you can in Haskell when the autolifting stuff makes it into GHC.

I'm not saying it'd be meaningful to have something like x : Maybe, but it does make talking about this stuff a bit more consistent. You just make sure there is no such x, so your logic doesn't let you prove anything you couldn't prove before.

I may be completely wrong here, but it doesn't seem all that ridiculous :)

Kinded things? Or, for a given kind, things of that kind? The whole point is that we don't know what to say, when speaking in English, and in a monad tutorial. Where * is on the right, types go on the left. This is the only case where we have something to say -- when speaking English, and in a monad tutorial. I was considering the thought that is best not to ruin this, the one piece of intelligible information, by declaring types to be whatever goes on the left of a kinding statement. Then there is no way into the kind system.

Yes, that's the point. Note that you are dogmatically affirming that the concept 'type (at the value level)' is not the same concept as 'value (at the type level)', where pumpkin presupposed their identity. They can indeed be forcibly identified, as I said, so that 'type = kinded thing', or 'type = value at the type level' . Then we will note that some types, interestingly enough, are, as you might say, types of things; in particular, types of kinds * and # have this curious property -- this use of the word "type" is natural where a kind system is up and running and you are communicating with fellow initiates. The consequence is that you only really know what a type is (in this sense) after you know what a kind is. But the original question (see above) was "what is a kind?"; if "type" now means: kinded thing then this is basically the same as the question "what is a type?", i.e. "what is a thing-that-has-a-kind"?

Note that you are dogmatically affirming that the concept 'type (at the value level)' is not the same concept as 'value (at the type level)'

No, on the contrary I said exactly that. A value at the type level is a type at the value level. Read my first sentence. Perhaps I was not clear because I was trying to also make the point that type functions are first-class values at the type level and value functions are first-class values at the value level, therefore a type-function is also a type-value and a value-function is also a normal value.

Now, Maybe is a function at the type-level (and thus also a value at the type-level), but maybe is NOT a value at the value level. You cannot pass a Maybe as a value to a function at the value level. Thus, something like this is meaningless at the value level:

f :: Maybe -> Int

... simply because functions only accept values at the type-level of kind (*). So to answer your question of "What is a kind?", the answer would be "The type of a type".

I was taking it as read that let foo :: Maybe; foo = undefined is a 'parse error' (see ghci) and thus that no one can affirm that Maybe is a 'type at the value level' -- to continue with this way of speaking. This, which you don't deny, contradicts the proposition that "A value at the type level is a type at the value level", which you now want to affirm. For Maybe is a 'value at the type level' as :k Maybe teaches us (this was your first sentence, which I did read). The converse (to continue with this jargon of levels) is true: "A type at the value level is a value at the type level". In particular it's a value of * or # or some other basic kind, at the type level.

If "x is the type of a type" means "x is the type of something that can be supposed, with out a parser error, to be the type of something" then your answer to the question, "what is a kind?", like pumpkin's, is "*", since that is the type (kind) of types. But this answer to the question 'what is a kind?' is of especially little use to someone who wants to understand * -> * -- or rather, to comprehend a monad tutorial where this is a way of formulating what the principal conceptual difficulty is.

Ok, now I see where you are coming from. You mean to say that Maybe is distinguished from a type like Int in that only Int can be used to type a value, therefore we must distinguish functions on the type level (i.e. Type constructors) from values on the type level, since they are not interchangeable for the purpose of typing values. I get you now.

I considered using separate notation for "type foo has kind bar", but I'm not aware of anything used besides foo :: bar to express such a thing. Anyways, you should be able to tell the difference because kind signatures use asterisks, while type signatures don't. In a way it's good that they look similar, though, per godofpumpkins' comment.

I think it's not possible to distill typeclassopedia further without loosing pedagogical efficiency. If you want to understand monads by taking the theory road, typeclassopedia is the best thing in the west. (And yes, do the exercises!)

For a practical introduction (seeing monad without knowing they are monads), the parser chapter of Graham Hutton's "Programming in Haskell" does a good job. This brings you some intuition about how to use monads.

The IO monad is too special to use it as a first example. I also think that monads should be learned after functors, monoids and applicative functors.

We need something similar to the Wadsworth constant but for monad tutorials. Or any tutorial, for that matter.

This tutorial is a perfect example of it. You want to write a tutorial? Don't waste your time on introductions, meta information or disclaimers: grab your readers by showing some code and dive right in.

The introductory meta information / disclaimers were so the reader knows exactly what to expect from my "monad tutorial". Perhaps using the word "tutorial" was misleading, which is why I felt the need to explain that I would not be "show[ing] some code and div[ing] right in".

I also wanted to make sure that readers were comfortable both with currying and with type and kind annotations, the latter of which I made heavy use of throughout the tutorial.

I still remember the first time I was learning how to make instances of the Arbitrary typeclass for my own types, and I realized that I could use fmap, or <$> and <*>, to define it very simply in terms of arbitrary for the subtypes.

I intentionally left "real world examples" out. I've thought about writing companion essays elaborating on the uses of particular monads, and actually started writing one for Maybe. But I wanted to keep this one as straightforward as possible, and delving into details about specific monads (without dedicating a significant amount of prose) often leads the reader to believe that "monads are for state/failure/nondeterminism/IO/whatever", which may lead to erroneous preconceptions when the reader is presented with a brand new instance of Monad.