'Alternative'类型类中的'some'和'many'函数

时间:2011-10-06 06:45:01

标签: haskell functional-programming typeclass

some类型类中的manyAlternative有哪些功能? Docs提供了一个我无法理解的递归定义。

2 个答案:

答案 0 :(得分:35)

somemany可以定义为:

some f = (:) <$> f <*> many f
many f = some f <|> pure []

查看some如何用monadic 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

首先MaybeNothing表示失败,因此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 fmany f将重复运行f,直到重试为止。我不确定这是否有用,但我猜它不是。

因此,对于Maybe[]STM manysome似乎没那么有用。只有当应用程序具有某种状态时才会有用,这种状态会在反复运行相同的事物时越来越有可能失败。对于解析器,这是每次成功匹配时收缩的输入。

答案 1 :(得分:8)

E.g。 for parsing(参见“通过示例解释”)。