In the article: "Write you a Haskell" (page 34) the following interpretation of "some
" and "many
" is given:
Derived automatically from the
Alternative
typeclass definition are themany
andsome
functions.many
takes a single function argument and repeatedly applies it until the function fails, and then yields the collected results up to that point. Thesome
function behaves similar except that it will fail itself if there is not at least a single match.
-- | One or more.
some :: f a -> f [a]
some v = some_v
where
many_v = some_v <|> pure []
some_v = (:) <$> v <*> many_v
-- | Zero or more.
many :: f a -> f [a]
many v = many_v
where
many_v = some_v <|> pure []
some_v = (:) <$> v <*> many_v
I have been trying to understand this implementation for a while.
I dont understand how "many
" and "some
" could be applied to "lists" or "Maybe
".
Also I am not sure about (:) <$> v <*> many_v
.
How does one derive this?
From
ghc/libraries/base/GHC/Base.hs
there is this recursive declaration:The argument
v
must be a value of a type that is instance ofAlternative
(andApplicative
andFunctor
).v
is lifted already and just needs to be applied (<*>
). The application results in a lifted list.some
andmany
make recursive applications of the constructor ofv
, and put the constructed values into a list.some
stops application, when the firstempty
is constructedmany
continues application beyond that[]
is instance ofAlternative
:some
tries with list:Comparing to
letter
in What are Alternative's "some" and "many" useful for?:with usage:
letter
is a smart constructor, that constructs a value ofP
with fieldrunP
using local variablep
. (The result of the accessor)runP
is a function.P
is a type implementingAlternative
as well as a constructor.P
stands for parser.fmap
is not used insome
andmany
.<*>
leads to an application of the functionrunP
, whose argument is not yet here. Basicallysome
andmany
construct a program that will eat from its argument. The argument must be a list. Due to laziness the recursion stops at the first constructor.Recursive application is not
empty
([]
for list), because there is no source of criteria to stop, i.e. no input.These stop:
There are more requirements on the argument of
some
andmany
(v
).v
is value of a type that is instance ofAlternative
.v
type must stop withempty
.v
must contain a function applied during construction with<*>
to have stop criteria.Conclusion:
some
andmany
cannot be applied to list values, even though list implementsAlternative
.Why does list implement
Alternative
? I think, it is to add theMonoid
interface<|>
andempty
on top ofApplicative
, not because ofsome
andmany
.some
andmany
seem to be just for parser construction or more generally construction of a program consuming input and producing more outputs, of which some can beempty
. That is quite general already. But the place inAlternative
is only justified, if most ofAlternative
instances have a sensible usage for it. That is not the case.