3 ms·
I had a dozen people try to describe Monads to me, many of them Haskell programmers. The one that finally made it click, was from a very senior Haskell dev who
by gavinray 5y ago
I had a dozen people try to describe Monads to me, many of them Haskell programmers.
The one that finally made it click, was from a very senior Haskell dev who said:
"People overcomplicate things. "Functor" is a fancy word for an interface that has the .map() method, and then "Monad" is a fancy word for a interface that has ".map" and ".flatMap" both"
Or something like that, I think. This probably isn't totally right, but IIRC it's something like this:
interface Functor<A> {
map: <B>(
transform: (a: A) => B,
a: A,
) => B[]
}
interface Monad<A> extends Functor<A> {
flatMap: <B>(
transform: (a: A) => B,
a: A,
) => B
}
Which helps me to think about it and understand it. None of the other explanations made any sense.
- still_grokking 5y agoThe explanation is kind of right but the code isn't. The map function needs to return a Functor<B> and flatMap takes a function A => Monad<B> and returns a Monad<B>. That's actually not 100% correct either as those are in fact higher kinds, so it's more like you have a generic F<_> that can be a functor or a monad or whatever, and the signature for functor map actually returns a F<B>, and flatMap takes a A => F<B>, returning a F<B>. It's quite easy to grok looking at Scala.
- chriswarbo 5y agoAs the sibling says, your code's a little off; but the approach of "they're just an interface" is the way I think of them too. We shouldn't forget the associated "functor laws" and "monad laws", but they're pretty intuitive and not much different than more mainstream rules; e.g. a 'Serialize' interface might have a "law" like 'Serialize.load(Serialize.save(x)) == x'