Для чего нужны функции some
и many
в классе типов Alternative
? документы предоставляют рекурсивное определение, которое я не мог понять.
«некоторые» и «многие» функции из класса типов «Альтернативный»
Ответы (2)
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
не кажутся такими уж полезными. Это полезно только в том случае, если аппликатив имеет какое-то состояние, которое увеличивает вероятность отказа при многократном выполнении одного и того же. Для синтаксических анализаторов это ввод, который уменьшается с каждым успешным совпадением.
Например. для анализа (см. раздел "Аппликативный анализ на примере").
p
для X, то some p
— это парсер для 0 или более X, а many p
— это парсер для 1 или более X.
- person Ingo; 06.10.2011
some
и many
реализованы с точки зрения <|>
. Этот комбинатор полезен и другими способами. Рассмотрим Either
: Just 0 <|> Just 1 = Just 0
, Nothing <|> Just 2 = Just 2
, Just 3 <|> Nothing = Just 3
, Nothing <|> Nothing = Nothing
- person fuz; 06.10.2011
Alternative
используется для чего-то еще. Можно сказать, что в целом some
используется всякий раз, когда вы хотите, чтобы что-то выполнялось несколько раз (но не обязательно для запуска), а many
— для запуска хотя бы один раз.
- person ivanm; 06.10.2011
some
и many
наоборот. some
равно одному или более (т.е. +
в регулярных выражениях), а many
равно нулю или более (т.е. *
).
- person Sjoerd Visscher; 07.10.2011
some
- это один или несколько, many
- это 0 или более результатов, полученных в результате многократного выполнения одних и тех же вычислений. поэтому, чтобы это имело смысл, должно иметь место некоторое прохождение состояния (и изменение), каким-то образом сокращающее область возможностей, иначе это будет повторяться до бесконечности. и передача состояния и синтаксический анализ тесно связаны.
- person Will Ness; 16.06.2020