In the article: "Write you a Haskell" (page 34) the following interpretation of "some" and "many" is given:
Derived automatically from the
Alternativetypeclass definition are themanyandsomefunctions.manytakes a single function argument and repeatedly applies it until the function fails, and then yields the collected results up to that point. Thesomefunction 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.hsthere is this recursive declaration:The argument
vmust be a value of a type that is instance ofAlternative(andApplicativeandFunctor).vis lifted already and just needs to be applied (<*>). The application results in a lifted list.someandmanymake recursive applications of the constructor ofv, and put the constructed values into a list.somestops application, when the firstemptyis constructedmanycontinues application beyond that[]is instance ofAlternative:sometries with list:Comparing to
letterin What are Alternative's "some" and "many" useful for?:with usage:
letteris a smart constructor, that constructs a value ofPwith fieldrunPusing local variablep. (The result of the accessor)runPis a function.Pis a type implementingAlternativeas well as a constructor.Pstands for parser.fmapis not used insomeandmany.<*>leads to an application of the functionrunP, whose argument is not yet here. Basicallysomeandmanyconstruct 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
someandmany(v).vis value of a type that is instance ofAlternative.vtype must stop withempty.vmust contain a function applied during construction with<*>to have stop criteria.Conclusion:
someandmanycannot be applied to list values, even though list implementsAlternative.Why does list implement
Alternative? I think, it is to add theMonoidinterface<|>andemptyon top ofApplicative, not because ofsomeandmany.someandmanyseem 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 inAlternativeis only justified, if most ofAlternativeinstances have a sensible usage for it. That is not the case.