It can't be done just by using what is provided by Applicative
. But Alternative
has a function that gives you power beyond Applicative
:
(<|>) :: f a -> f a -> f a
This function lets you "combine" two Alternatives
without any restriction whatsoever on the a
. But how? Something intrinsic to the particular functor f
must give you a means to do that.
Typically, Alternative
s require some notion of failure or emptiness. Like for parsers, where (<|>)
means "try to parse this, if it fails, try this other thing". But this "dependence on a previous value" is hidden in the machinery implementing (<|>)
. It is not available to the external interface, so to speak.
From (<|>)
, one can implement a zero-or-one combinator:
optional :: Alternative f => f a -> f (Maybe a)
optional v = Just <$> v <|> pure Nothing
The definitions of some
an many
are similar but they require mutually recursive functions.
Notice that there are Applicative
s that aren't Alternative
s. You can't make the Identity
functor an Alternative
, for example. How would you implement empty
?