Для чего нужны функции some и many в классе Alternative типов? Документы дают рекурсивное определение, которое я не смог понять.
функции 'some' и 'many' из класса 'Alternative'
Ответ 1
some и many можно определить как:
some f = (:) <$> f <*> many f
many f = some f <|> pure []
Возможно, это помогает увидеть, как some будет написан с монадическим синтаксисом do:
some f = do
x <- f
xs <- many f
return (x:xs)
Итак some f запускает f один раз, затем "много" раз и сохраняет результаты. many f запускает f "несколько" раз, или "альтернативно" просто возвращает пустой список. Идея состоит в том, что они оба запускают f настолько часто, насколько это возможно, пока не "не удастся", собирая результаты в списке. Разница заключается в том, что some f терпит неудачу, если f немедленно сбой, а many f преуспеет и "возвращает" пустой список. Но то, что это все означает, точно зависит от того, как <|> определено.
Это полезно только для синтаксического анализа? Посмотрим, что он делает для экземпляров в базе: Maybe, [] и STM.
Сначала Maybe. Nothing означает сбой, поэтому some Nothing также терпит неудачу и оценивается как Nothing, а many Nothing - с ошибкой Just []. Оба some (Just ()) и many (Just ()) никогда не возвращаются, потому что Just () никогда не сработает! В некотором смысле они оценивают значение Just (repeat ()).
Для списков [] означает сбой, поэтому some [] оценивает [] (нет ответов), а many [] оценивается как [[]] (есть один ответ, и это пустой список). Опять some [()] и many [()] не возвращаются. Расширение экземпляров some [()] означает fmap (():) (many [()]) и many [()] означает some [()] ++ [[]], поэтому вы можете сказать, что many [()] совпадает с tails (repeat ()).
Для STM отказ означает, что транзакция должна быть повторена. Таким образом, some retry повторит попытку, а many retry просто вернет пустой список. some f и many f будут запускать f несколько раз, пока он не повторит попытку. Я не уверен, что это полезная вещь, но я предполагаю, что это не так.
Итак, для Maybe, [] и STM many и some, похоже, не так полезны. Это полезно только в том случае, если в аппликативном состоянии есть какое-то состояние, которое делает сбой более вероятным при повторении одного и того же предмета снова и снова. Для парсеров это вход, который уменьшается с каждым успешным совпадением.
Ответ 2
например. для разбор (см. раздел "Аппликативный синтаксический анализ на примере" ).