3 ms·
This article is playing fast and loose and I think gives a false understanding of what functors and monads are. In particular there is an unwarranted leap here
by dwohnitmok 5y ago
This article is playing fast and loose and I think gives a false understanding of what functors and monads are.
In particular there is an unwarranted leap here. If `numToStr` is a functor, then `addOne` (the function that just adds one to an integer) should be an endofunctor. So what's the monad?
Yet all of a sudden the article jumps to talking about `Array` as an endofunctor! Which is most definitely not a function like `numToStr` or `addOne`.
So which is it?
In particular,
> Of course, as we saw above, Arrays support a map method which allow us to transform the values of the array but do so in a way that returns an Array (the same type as the starting type), making them endofunctors.
Makes no sense combined with `numToStr`. What exactly is the `map` function for `numToStr`?
It turns out you can unify both of these notions, but you need the language of category theory to do it. But that's overkill for FP. So generally in FP a functor is just a type constructor (a type that takes another type as an argument e.g. `List<A>` or `Option<A>` or `Future<A>`) with an associated `map` function that obeys the "law" that `map`ing the identity function does nothing.
The full category theory definition requires a bit more exposition than just thinking of things as sets and functions. In particular you need to talk about two levels of mappings: mappings between categories, which are functors, and mappings between functors themselves, which are natural transformations. A monad is then a functor from a category to itself with two associated natural transformations. If the functor and natural transformations are taken as objects and arrows/morphisms in a category itself, then it forms a monoid. This is why we can also think of a monad as a monoid.
This sort of "category-stacking" where mappings between categories are treated as categories themselves where we can then further discuss another level of mapping between them, is the core of category theory.
- jkhdigital 5y ago> This sort of "category-stacking" where mappings between categories are treated as categories themselves where we can then further discuss another level of mapping between them, is the core of category theory. I've started to call it "fractal math". Not to be interpreted as the mathematics of fractals, but rather as mathematics which is itself structured as a fractal (metaphorically speaking, of course).
- IndexPointer 5y agoYeah, it's very confusing. Array is a monad. Then what's the function that takes an array and returns another? Is it map? That can't be because map takes two parameters, not one: the array and a function that it will apply to every element. Something is missing in the explanation. And why is Option a monad? What's the associative function that takes two options and returns another Option?
- light_hue_1 5y agoLeaving the confusing article aside. Practically, the additional function that monads support is usually called bind and looks like: Array a -> (a -> Array b) -> Array b This is different from map which is: Array a -> (a -> b) -> Array b Notice how in map, your function returns a value that isn't lifted in the monad. The bottom one is a functor, the top one is a monad. Functors let you visit an array at every element. Monads let you visit an array and produce a new array each time and they internally decide how they will recombine those values. This is a bit silly for Array, you just concatenate the outputs. But is more interesting for Option. map for Option looks like: Option a -> (a -> b) -> Option b It says "If there's anything in my Option, apply this function to it, otherwise there's still nothing there" bind for Option looks like: Option a -> (a -> Option b) -> Option b It says "If there's anything in my Option, run this computation. This computation can also return an option". In this sense, it lets you string together computations that each produce optional values. The whole computation will fail if any part fails. Something that is very useful!
- IndexPointer 5y agoThanks for the explanation! The Option example makes perfect sense.