3

我已经阅读了这篇文章的一些替代含义(很长)

引导我去那篇文章的原因是Alternative总体上了解。这篇文章给出了一个很好的答案,解释了为什么它是以它的方式实现的List

我的问题是:

  • 为什么要Alternative实施List呢?

是否可能有一种算法使用Alternative并且List可能会传递给它,所以定义它以保持一般性?

我想是因为Alternative默认情况下定义了someand many,这可能是其中的一部分,但是What are some and many useful for包含评论:

澄清一下somemany对于最基本的类型的定义,例如[]Maybe只是循环。所以虽然somemany对它们的定义是有效的,但它没有任何意义。

在上面的“什么是一些有用的”链接中,Will 对可能包含我的问题的答案的 OP 给出了答案,但是在我的 Haskelling 中,森林有点厚,看不到树木。

谢谢

4

3 回答 3

2

Haskell 库生态中有一个约定,如果一个东西可以是类的实例,那么它应该是类的实例。我怀疑“为什么是[]一个Alternative?”的诚实答案。是“因为它可以”。

...好的,但是为什么存在该约定?简短的回答是,实例是 Haskell 中只屈服于整个程序分析的一部分。它们是全局的,如果程序的两个部分都试图进行特定的类/类型配对,那么这种冲突会阻止程序正常工作。为了解决这个问题,有一条经验法则,即您编写的任何实例都应该与其关联的类或与其关联的类型存在于同一个模块中。

由于实例应该存在于特定的模块中,因此尽可能定义这些实例是有礼貌的——因为另一个库试图修复您没有提供实例的事实是不合理的。

于 2021-12-11T03:07:37.237 回答
1

[]当将其视为非确定性单子时,替代方案很有用。在这种情况下,<|>表示两个程序之间的选择,并empty表示“没有有效的选择”。这与解析器的解释相同。

some并且many确实对列表没有意义,因为它们尝试从给定选项的所有可能的元素列表中贪婪地迭代,从第一个选项的无限列表开始。list monad 也懒得去做,因为如果给它一个空列表,它可能总是需要中止。然而,当两者都终止时,有一种情况:当给定一个空列表时。

Prelude Control.Applicative> many []
[[]]
Prelude Control.Applicative> some []
[]

如果somemany被定义为惰性(在正则表达式意义上),这意味着他们更喜欢短列表,您会得到结果,但不是很有用,因为它首先使用第一个选项生成所有无限数量的列表:

Prelude Control.Applicative> some' v = liftA2 (:) v (many' v); many' v = pure [] <|> some' v
Prelude Control.Applicative> take 100 . show $ (some' [1,2])
"[[1],[1,1],[1,1,1],[1,1,1,1],[1,1,1,1,1],[1,1,1,1,1,1],[1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1],[1,1,1,1,1,"

编辑:我相信someandmany函数对应于一段star-semiring时间<|>empty对应于半环中的加号和零。所以在数学上(我认为),将这些操作拆分为一个单独的类型类是有意义的,但这也有点愚蠢,因为它们可以根据Alternative.

于 2021-12-11T09:31:35.597 回答
0

考虑这样的函数:

fallback :: Alternative f => a -> (a -> f b) -> (a -> f e) -> f (Either e b)
fallback x f g = (Right <$> f x) <|> (Left <$> g x)

意义不大,但您可以想象它被用于解析器:尝试一件事,如果不起作用,则退回到另一件事。

这个函数在什么时候有意义f ~ []?当然,为什么不呢。如果您将列表的“效果”视为在某个空间中的搜索,那么此功能似乎代表某种有偏见的选择,您更喜欢第一个选项而不是第二个选项,虽然您愿意尝试任何一个,但您也标记你走了哪条路。

像这样的函数可以成为它计算的替代方案中的多态算法的一部分吗?我不明白为什么不这样做。有一个 Alternative 实例似乎不是不合理的[],因为有一个满足 Alternative 法律的实现。

至于您指出的 Will Ness 所链接的答案:它涵盖了这一点,some并且many 不会“仅循环”列表。它们循环查找非空列表。对于空列表,它们会立即返回一个值。这有多大用处?可能不是很,我必须承认。但是该功能与(<|>)and一起提供empty,这可能很有用。

于 2021-12-11T02:50:49.273 回答