21

类型类中的功能some和用途是什么?文档提供了一个我无法理解的递归定义。manyAlternative

4

2 回答 2

44

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在这种情况下仍然会成功并“返回”空列表。但是这一切究竟意味着什么取决于如何<|>定义。

它只对解析有用吗?让我们看看它对 base Maybe:[]STM.

首先MaybeNothing表示失败,因此some Nothing也失败并评估为,Nothingmany 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,直到重试。我不确定这是否有用,但我猜它不是。

所以, for和 andMaybe似乎[]没那么有用。仅当应用程序具有某种状态时,它才有用,这种状态 在一遍又一遍地运行相同的东西时使失败的可能性越来越大。对于解析器,这是随着每次成功匹配而缩小的输入。STM manysome

于 2011-10-06T22:39:22.710 回答
8

例如用于解析(参见“通过示例进行应用解析”部分)。

于 2011-10-06T07:12:28.770 回答