some
类型类中的many
和Alternative
有哪些功能? Docs提供了一个我无法理解的递归定义。
答案 0 :(得分:35)
some
和many
可以定义为:
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
。
首先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
似乎没那么有用。只有当应用程序具有某种状态时才会有用,这种状态会在反复运行相同的事物时越来越有可能失败。对于解析器,这是每次成功匹配时收缩的输入。
答案 1 :(得分:8)
E.g。 for parsing(参见“通过示例解释”)。