类型类中的功能some和用途是什么?文档提供了一个我无法理解的递归定义。manyAlternative
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在这种情况下仍然会成功并“返回”空列表。但是这一切究竟意味着什么取决于如何<|>定义。
它只对解析有用吗?让我们看看它对 base 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,直到重试。我不确定这是否有用,但我猜它不是。
所以, for和 andMaybe似乎[]没那么有用。仅当应用程序具有某种状态时,它才有用,这种状态 在一遍又一遍地运行相同的东西时使失败的可能性越来越大。对于解析器,这是随着每次成功匹配而缩小的输入。STM manysome
例如用于解析(参见“通过示例进行应用解析”部分)。