类型类中的功能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
在这种情况下仍然会成功并“返回”空列表。但是这一切究竟意味着什么取决于如何<|>
定义。
它只对解析有用吗?让我们看看它对 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
many
some
例如用于解析(参见“通过示例进行应用解析”部分)。