As other answers have pointed out, Haskell tends to use different vocabulary. However, I don’t think they’ve explained the reason for the difference very well.
In a language like Java, functions are not “first class citizens”; it’s true that anonymous functions are available in the latest versions, but this style of interface (Collection, Indexable, Interable, etc.) were designed before that.
This makes it tedious to pass our code around, so we prefer other people’s data to be passed to our code. For example:
- Data implementing Java’s
Iterable
lets us writefor (Foo x : anIterable) { ... }
- Data implementing PHP’s
ArrayAccess
lets us writeanArrayAccess[anIndex]
This style can also be seen in OO languages which implement generators, since that’s another way for us to write for yieldedElement in aGenerator: ...
.
Haskell takes a different approach with its typeclasses: we prefer our code to be passed to other people’s data. Some (simplified) examples:
Functor
s accept our code and apply it to any elements they ‘contain’Monad
s accept our code and apply it in some kind of ‘sequence’Foldable
s accept our code and use it to ‘reduce’ their contents
Java only needs Iterable
since we have to call our code in our for
loop, so we can make sure it’s called correctly. Haskell requires more specific typeclasses since someone else’s code will be calling ours, so we need to specify how it should be called; is it a map
, a fold
, an unfold
, etc.?
Thankfully, the type system helps us choose the right method 😉