“Alternative”类型类中的“some”和“many”函数

22
< p >在 Alternative 类型类中,函数 some many 有什么用处?文档提供了一个递归定义,我无法理解。


@Landei:我看了那个帖子中的答案,但我仍然不明白。 - missingfaktor
我只是说这个问题是一个重复的,而不是原来的那个有一个好的答案 :-) 尽管对我来说已经足够好了:我发现这些函数对我来说很可能不是很有趣... - Landei
@Landei:我得出了和你一样的结论。 :-) - missingfaktor
如果您要关闭此问题,请将其与@Landei的合并。不要删除它。 - missingfaktor
2个回答

44

somemany 可以定义为:

some f = (:) <$> f <*> many f
many f = some f <|> pure []

也许看一下使用单子 do 语法如何编写 some 会有所帮助:

some f = do
  x <- f
  xs <- many f
  return (x:xs)

所以,some f 执行 f 一次,然后“多次”运行,并将结果组合成列表。 many f 运行 f“某些”次数,或者“另外”只返回空列表。其想法是它们都尽可能地运行 f 直到它“失败”,并将结果收集在列表中。区别在于,如果 f 失败,some f 将立即失败,而 many f 在这种情况下仍将成功并“返回”空列表。但所有这些的确切意义取决于如何定义 <|>

它只对解析有用吗?让我们看看它对基础实例 Maybe[]STM 的影响。

首先看 MaybeNothing 表示失败,因此 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 fmany f 将反复运行 f 直到它重试。我不确定这是否有用,但我猜它不是。

所以,对于 Maybe[]STMmanysome 看起来并不是那么有用。它只在applicative具有某种状态使得多次运行相同内容时失败变得“越来越”可能的情况下才有用。对于解析器,这是与每个成功匹配相关联的缩小输入。


1
some (Just ()) 等于 Just (repeat ()) 有点误导人,即使加了 "在某种意义上" 的限定,因为这使我想知道像 some (Just ()) >>= return . head 这样的表达式是否会像 Just (repeat 1) >>= return . head 那样运行,但事实并非如此;后者终止而前者不会。 - Ose

8
例如,对于解析(请参见“应用解析示例”部分)。

2
我不熟悉Parsec。能否请您解释一下? - missingfaktor
2
据我所知,如果您有一个用于X的解析器p,那么some p是0个或多个X的解析器,而many p是1个或多个X的解析器。 - Ingo
2
@missingfaktor somemany 是基于 <|> 实现的。这个组合器在其他方面也很有用。考虑 Either: Just 0 <|> Just 1 = Just 0, Nothing <|> Just 2 = Just 2, Just 3 <|> Nothing = Just 3, Nothing <|> Nothing = Nothing - fuz
1
@missingfaktor:那是通常的应用程序;我不确定 Alternative 是否用于其他任何事情。你可以说,“一般来说”,当你想让某些东西运行多次(但不必须运行)时使用 some,而使用 many 至少运行一次。 - ivanm
3
注意,您将“some”和“many”颠倒了。 “some”表示一个或多个(即正则表达式中的“+”),而“many”表示零个或多个(即“*”)。 - Sjoerd Visscher
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接