Then why didn't they just call those types "Mappables"?
Then why didn't they just call those types "Mappables"?
What do you call the following common operations?
- 1 + 0
- 1 * 1
- "string" ++ ""
- [1, 2, 3] ++ []
As far as I know there is no term for this grouping of operations outside of functional programming languages which use category theory.We call it a "monoid" based on the following precise definition:
> In abstract algebra, a branch of mathematics, a monoid is an algebraic structure with a single associative binary operation and an identity element[1].
I used the "identity element" specifically in my examples above since they tend to be a good way to grasp what is going on.
It turns out a "functor" has more properties than just being "mappable", which is why we like using the more precise term in our literature. However, it's still a decent intuition if you aren't familiar with the concept.
For example, in the parent comment the 'f' in the second line of code shows that it is some kind of structure that adheres to a Functor, and also infers that this structure can also be mapped over. This is a nice property because without caring about the implementation, we can still do functor-specific operations over abstract structures.
I think the point GP was making is that a monoid has something to do with a function f that takes two arguments a and b where there is a single value for b such that f(a, special_value) == a. I think.
As someone who doesn't really understand FP concepts I would probably call those functions "functions that can sensibly be used in a call to array.reduce"
+: concat marbles sequence
* : concat prime factors sequence
++: concat box sequence
For * , it can also be reduced to + via logarithms. I just don't have a good metaphor for '+ over reals' this morning.
Given that this is a thread on functional jargon, it might be interesting to note list metaphors as being useful for thinking about monoid might derive from lists being free monoids (in many contexts). This means that all functions from a collection elements to a monoid can be thought of as functions from that collection into a list with the appropriate type of elements and then a fold (also called a reduction) over that list. This knowledge can be super useful for thinking about program structure e.g. conceptually mapreduce is a general tool for large-scale distributed computation over monoids.
*it’s actually called “mappend”[0], short for monoid append, but I think the point still stands (and there is, in fact, a function called “mconcat”[1] but folds of a list of monoidal values using “mappend” to combine them.)
[0] http://hackage.haskell.org/package/base-4.14.0.0/docs/Data-M...
[1] http://hackage.haskell.org/package/base-4.14.0.0/docs/Data-M...
Skimming through my thesaurus, I found a word for it: "Totalize".
You can use any function you want in a fold in Haskell. You're conflating two typeclasses, Monoids and Foldables, and restricting yourself to the function known in Haskell as foldMap.
"associative": (a + b) + c == a + (b + c)
"binary": f a b == a `f` b == a + b where f is addition
"identity element": the "empty" value which when paired with a second value, returns the second value as is
So reduceables?
That said, I am on the "name abstractions after the math" side of things. It makes it much clearer what guarantees I have when working with the interface, on either side of it.
“Functor,” points to a specific concept in Haskell and a slightly different one in Category Theory but otherwise it is fairly unambiguous given enough context. The concept not only refers to the type and the associated “map” operation but also the axioms of identity and composition and their properties.
“Mappable,” is a very common name people pick in these discussions but it doesn’t clarify the meaning any more than calling it “Rose.” It may in fact cause more harm than good if a name like Mappable exists in more contexts. There are plenty of objects one can apply a map operation to that are not valid Functors.
> The short form was really adopted as a mischievous pun on the use of "functor" in the OOP community.
Citation needed.
I just have never heard that allegation about `functor`, which seems to have been taken directly from mathematics that predate any notion of function object. It's possible that OO programmers and the mathematicians both borrowed it from the same source (it seems to have originated in linguistics).
That's been debated in philosophy for over 150 years, and there are many alternative theories.
I think a better point is that technical names don't matter because their formal meaning may not correspond with any word, and if there is an everyday word, it's probably slightly but importantly different.
Though now that FP concepts are mainstream, I think there is a good case to offer some friendlier, more familiar names:
Functor -> Mappable
Applicative -> Pairable
Monad -> Thenable
[0]: https://softwareengineering.stackexchange.com/questions/2033...
I've been writing Haskell for over 5 years and to this day when I see <$>, <*>, >>= in my code I don't substitute English words for them.
mentalModel.update().
The query `python @` fails pretty hard though.
:info (>=>)Citation needed
Calling Functor "Mappable" and Monad "Thenable" doesn't really add much to understanding.
The best advice I ever got was that a Functor is `f` with a function `fmap :: (a -> b) -> f a -> f b` that follows its laws. Same goes for Monad. If it has the type signature & follows the laws, it's a Monad. That's the definition. No need for a cute analogy-oriented name like FlatMap-able or Then-able.
Once you do that, you realize that the way to understand these things is to play type tetris with highly-generic type signatures. You stop needing English/real-world analogies to understand them and instead use the type system to understand the world (the reverse of using "nice" names)
It works really well but it is a steep hill to climb. It helps to talk to others who have climbed it, and it helps to just grind on a project and use Monads without being an expert. You can go a long way just knowing how `do`, `traverse`/`mapM`, etc work and not having big Monad intuition.
Citation needed.