Go doesn't have monads. The closest Go feature is perhaps either a range loop or the extinct exp/iterable package, but they are as close to monads as Go's interfaces are to C++'s virtual multiple inheritance (i.e. in that direction, but nowhere near).
I know little about Go. But like you, I had no idea what monads were, until one day, after giving a presentation on promises in Play, I told someone I didn't know what a monad was, and they pointed out to that I just gave a presentation on monads. Then it all made sense. Maybe I can explain my learnings to you. Since I don't know Go, let's choose a boring language that we both know, Java. And I'll choose Java 8, because I'm typing this on my phone and monads requires passing functions.
Let's say I want to call a webservice. This webservice has two end points, a search endpoint, that given a search query returns a list of IDs. And then a details endpoint, that given an id, returns the details of the entity. So if I have a query, and I want to get the details for the entity that match that query, then I need to do two calls, the search call followed by the details call.
Now I'm going to use an asynchronous http client. Since we're in Java, we don't have all these lightweight processes or whatever it is Go provides. Instead we'll use Promises, and let's assuming I've already written a Java API that does the HTTP stuff so I can just make high level API calls. So the first call gives me back a String id, so it's going to return me a Promise<String>. This says at some point in future, a string will be available. While you might be able to call get() on it and block, that defeats the point of using an asynchronous client. So in practice you never call get, rather, you attach callbacks to it that get executed when the promise is redeemed with the string id.
So, here's our code:
Promise<String> idPromise = doSearchQuery(someQuery);
So now we want to do something with id when it's redeemed. We could attach a plain side effecting callback when it's done, but since we are functional zealots (we are aren't we?), side effects are evil. Instead, we're going to transform our promise to a promise of the details that will be returned by the details endpoint. You can easily transform a promise from one thing to another using a call called map, for example, maybe the ids are actually integers, so we we could convert it to Promise<Integer> like this:
Promise<Integer> intId = idPromise.map(id -> Integer.parseInt(id));
So now we have a promise for the id as an integer, when the id string becomes available, our callback gets executed, and then any callbacks attached to the new promise will be executed.
But in our case, because what we want to do with the id is make another asynchronous call that returns a Promise<Details>, not just Details, if we used map, we'd end up with Promise<Promise<Details>>. So instead, we use a call called flatMap, which is so called because it does a map, but then it also flattens the promise of a promise to a single promise. So the code looks like this:
Promise<Details> detailsPromise = idPromise.flatMap(id -> lookUpDetails(id));
So, when the id is redeemed, our callback to look up the details gets executed, it returns a promise, and the detailsPromise that we now have is redeemed when that promise is redeemed. And so we can then attach more map and flatMap calls, and so on.
And that is a monad. Anything with a flatMap method is a monad. Not just promises, anything that holds items of a certain type that can be transformed to another type can be a monad. A set can be a monad for example, you have a set of people, and you want a set of all their kids, if you map it you'll get a set of sets of kids, if you flatMap, you get a single set of all the kids together.
The reason why no one can explain them is they always try to explain things in the general sense, for which there is no concrete use case. But start with an implementation of a monad, such as promise, and at least for me, it's much easier to learn (or maybe you'll realise you always knew it).
So does Go have monads? If Go allows passing functions, then you could probably implement monads in Go.
Hope that helps,
James
Oops, missed that. Doug didn't realize the extra special meaning it would have for this group.
--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/iIAhrtK8XRo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.