From the class's name and usage in parsers and with Maybe I thought that it's behaviour would be to choose the first non-empty input from a <|> b <|> c. So I expected that for input
[] <|> [1] <|> [2, 3]
it would return the first non-empty list, i.e.:
[1]
but it actually just concats the whole thing, producing:
[1,2,3]
So I am wondering what's the reasoning behind such an implementation? Is it actually correct?
P.S. Is there any standard function that does what I expected from Alternative?
When implementing an
Alternative f(orMonadPlus f) instance, you have to select a monoid overf aand implement it usingemptyand<|>. For some structures, such as lists, there can be several possibilities. The most natural monoidal operation for lists is their concatenation (with[]being the identity element). Taking the first non-empty element, as you suggest, is also a possibility, but not as natural for lists. Your operation almost ignores the structure (the length) of lists, it only checks if a list is empty or not. And it doesn't add anything new, because this kind of monoidal operation is already available asMaybe's instance ofAlternative, which is designed to represent (non)empty values.This is also reflected in the instance of
MonadPlusof[]. As described on HaskellWiki, there are two possible sets of laws for instances ofMonadPlus:[]Maybe,IOandSTM.If we chose your implementation of
AlternativeandMonadPlus, then we'd have only instances satisfying... + LeftCatch, nothing satisfying LeftDistribution. And again,MonadPlusof[]wouldn't be very different fromMonadPlusofMaybe. And we wouldn't have anything that would enable us to solve things like the send+more=money puzzle. So it's much more interesting to choose themplus/<|>of[]to be concatenation.