Hacker News new | past | comments | ask | show | jobs | submit login

If monads exist outside of Haskell, why isn't there a text which explains them with out Haskell knowledge? Where would I find such a text and description?

I would really like to understand what they are, but so far have not been able to find any explanation which tries to explain them in terms of english, math or some commonly known programming language.




This is probably the best resource I've come across for discussing this subject: https://fsharpforfunandprofit.com/posts/elevated-world/


Thanks, but the article loses me at what this "elevated world" is. It doesn't even try to explain what it is and quickly goes over to F# syntax, which I don't understand. Why is there no explanation in the terms of English, math, and any common programming language? If Functors and Monads are real concepts, they should be describable in the terms listed above, if they are only describably in terms of functional languages, I would consider them a pure artifact of those languages :)


There's a problem here as the author himself notes.

I can provide you a simple example of a function with monadic interface, you will understand it any language but that will not actually help you to conceptualize the idea of monads and influence your thinking.

You will just think that's simple, whats the fuss about it and miss the pattern altogether.

Imagine asking the user to provide a number, in most languages you will get a `string | null` value and you wish to get a real number from it by parsing the string if the user entered it.

In this case assuming you have a function `parseNo` that goes from `string -> int | null` you can create a special function which takes a `string | null` value along with the `parseNo` function and gives you back `int | null`. S

Turns out that function can be defined for many different data types and it has special useful properties.

In this case it allows us to compose functions neatly, without having to do a whole bunch of null checks.

But in other scenarios it can do a lot more.


Sounds like you are describing high order functions as they are known from Lisp?


Yes higher order functions. A function that takes a function as an argument or returns a function. In lisp you can think of a higher order function as taking data, processing it and then returning it just like any other normal function because code is data.


You have a container with `a` inside, let's call the container `m`. You have `m a`.

You can provide a function with the type signature `a -> b`. With this we run the function underneath `m` and map `m a -> m b`.

Concretely this might be with for example lists, where given a function `Int -> String` I can map `[Int] -> [String]`. What the functor abstraction gives you is a consistent, lawful way to define this phenomenon for virtually every type you'd ever want to "map". Likewise monads for "flat mapping".

This explanation was 90% accurate. What's missing is that not every functor or monad is a "container", for example Haskell's `IO`, which rather represents an action of sorts to impurely get a value. But the intuition will build all the same if you play with it a bit. It's all in the type signatures.


Say you have a source of A, and a way of turning an A into a source of B. An operation that uses these two inputs to produce a source of B is a monad.

This is about 90% of the way there (and TFA actually contains very similarly phrased description, right before the monad definition you complained about).

The problem is that English does not have the right words to describe the abstract idea behind "source", "way of" and "operation" precisely and rigorously.

Regarding "any common programming language": In a way, this is like trying to explain a concept like, say, "the adjoint operator" [0] to someone only aware of integers. Or trying to explain the idea of the Liskov Substitution Principle [1] to someone who just learned assembly.

In each case above, the language used to describe the concept is multiple layers of abstraction too low to succinctly ping down the concept in question. Haskell brings (or rather is) a very rich language suited specifically for accurately describing the elements involved. That's why 1) the concept of a Monad is visible/cleanly expressible in the first place, and 2) people use it to explain the concept, even when (like this blog post) not aiming at a Haskell (or Haskell learner) audience.

Disclaimer: I'm just a lowly OOP programmer, not written a line of Lisp or Haskell in my life. Watching from the sidelines for now.

[0]: https://en.wikipedia.org/wiki/Hermitian_adjoint

[1]: https://en.wikipedia.org/wiki/Liskov_substitution_principle


Say you have a source of A, and a way of turning an A into a source of B. An operation that uses these two inputs to produce a source of B is a monad.

Did you mean to write "Say you have a source of A, and a way of turning an A into a B. An operation that uses these two inputs to produce a source of B is a monad"?

What exactly do you consider a "source"? And the way of turning an A into a B I would call a function. And combining the "source of A" with a function that converts A's into B's, a concationation or composition of functions, or a way of currying.

And yes, I am fully aware, that you sometimes need to learn the vocabulary to have a minimum discussion. But considering I have a degree in math and CS, have learned at least 10 programming languages, especially Lisp with all of its contexts, I am highly suspicious about something that cannot expressed in plain language. But thanks, your explanation comes closest I have seen so far.


> Did you mean to write "Say you have a source of A, and a way of turning an A into a B. An operation that uses these two inputs to produce a source of B is a monad"?

No. That would be the Functor concept explained in TFA. A Monad is specifically what I wrote.

> And combining the "source of A" with a function that converts A's into B's, a concationation or composition of functions, or a way of currying.

Yes, pretty much. See the article (where one of the main points is specifically that the functor concept is not a highly complex thing. Just a name for a kind of thing - an abstraction).

> What exactly do you consider a "source"?

That's exactly the point where the "genericness" of the concept (consider: it originates from category theory) precludes discussing it in more specificity. It could be a Maybe<A> (std::optional in C++), it could be a List<A>, it could be a PotentialFutureUserInput<A> (aka IO in Haskell), it could be a (C#) Enumerable... Anything that "wraps" (in any sense) another type. A functor allows you to apply a function that transforms the inner type into another without leaving the wrapper. A monad allows you to apply a function to the inner type, transforming it into a different now wrapped type, with the monad implementation taking care of "flattening" the wrappers. I will avoid the attempt to come up with an example, seeing as the article also criticizes the abundance of bad monad examples.

Here, I've written a C++20 concepts version of Monad. Well, I hope I did. But even if correct, it's just not something C++ can express well, much less use well: Since functions are not first-class citizens, you can't spell "a function from A to M<B>" in a way the compiler can deduce. That's why you need the extra template argument F and corresponding constraint FAMB.

https://godbolt.org/z/b3PoPYeE9


There isn't one unique elevated world, as he goes on to say. Two he lists we are familiar with - options and lists. If you've ever used Option(Some|None) and pulled out a value from Some - the Option is the elevated world, the Some|None is the elevated value.


In most languages you will lack the Monad type and helper functions, and you'll have available many shortcuts that undermine efforts to set up monadic expressions.

So something can behave similarly to a monad, but the type systems don't stop you self-sabotaging your code or misunderstanding good composition.

Best way to learn is to learn Haskell deliberately. Better than Go, the language forces you to compose better code, and even learn the values of FP.

If one is uninterested in learning CS or expanding one's toolbelt, it'll take some years until industry catches up.


So you are saying you cannot describe what a Monad is without the presense of a FP language?


I didn't say that. Learning Haskell may help the budding learner, though won't enforce the monadic laws.


The entire body of category theory is where all of this stuff comes from originally, not Haskell.

> tries to explain them in terms of english, math

There are a million English-language blog posts, and it’s a mathematical concept. Just look up “monads are monoids in the category of endofunctors” if you want more of that…


I was looking for a simple explanation about what a Monad could be, not a mathematical theory.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: