Alternative
类型类中的函数some
和many
有什么用呢?Docs提供了一个我无法理解的递归定义。
发布于 2011-10-07 06:39:23
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
,直到它“失败”,将结果收集到一个列表中。不同之处在于,如果f
立即失败,则some 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
,直到它重试。我不确定这是不是有用的东西,但我猜它不是。
因此,对于Maybe
来说,[]
和STM
many
和some
似乎没有那么有用。只有当应用程序具有某种状态,在反复运行相同的事情时,使失败的可能性增加时,它才是有用的。对于解析器,这是每次成功匹配时都会缩小的输入。
发布于 2011-10-06 15:12:29
例如,对于parsing (参见“通过示例进行应用解析”部分)。
https://stackoverflow.com/questions/7671009
复制相似问题