(<|>) :: f a -> f a -> f a
actually tells you quite a lot, even without considering the laws for Alternative
.
It takes two f a
values, and has to give one back. So it will have to combine or select from its inputs somehow. It's polymorphic in the type a
, so it will be completely unable to inspect whatever values of type a
might be inside an f a
; this means it can't do the "combining" by combining a
values, so it must to it purely in terms of whatever structure the type constructor f
adds.
The name helps a bit too. Some sort of "OR" is indeed the vague concept the authors were trying to indicate with the name "Alternative" and the symbol "<|>".
Now if I've got two Maybe a
values and I have to combine them, what can I do? If they're both Nothing
I'll have to return Nothing
, with no way to create an a
. If at least one of them is a Just ...
I can return one of my inputs as-is, or I can return Nothing
. There are very few functions that are even possible with the type Maybe a -> Maybe a -> Maybe a
, and for a class whose name is "Alternative" the one given is pretty reasonable and obvious.
How about combining two [a]
values? There are more possible functions here, but really it's pretty obvious what this is likely to do. And the name "Alternative" does give you a good hint at what this is likely to be about provided you're familiar with the standard "nondeterminism" interpretation of the list monad/applicative; if you see a [a]
as a "nondeterministic a
" with a collection of possible values, then the obvious way for "combining two nondeterministic a
values" in a way that might deserve the name "Alternative" is to produce a nondeterminstic a
which could be any of the values from either of the inputs.
And for parsers; combining two parsers has two obvious broad interpretations that spring to mind; either you produce a parser that would match what the first does and then what the second does, or you produce a parser that matches either what the first does or what the second does (there are of course subtle details of each of these options that leave room for options). Given the name "Alternative", the "or" interpretation seems very natural for <|>
.
So, seen from a sufficiently high level of abstraction, these operations do all "do the same thing". The type class is really for operating at that high level of abstraction where these things all "look the same". When I'm operating on a single known instance I just think of the <|>
operation as exactly what it does for that specific type.