简体   繁体   English

Haskell - 为什么要为 List 实施 Alternative

[英]Haskell - Why is Alternative implemented for List

I have read some of this post Meaning of Alternative (it's long)我已经阅读了这篇文章的一些替代含义(很长)

What lead me to that post was learning about Alternative in general.让我看到那篇文章的原因是总体上了解了Alternative The post gives a good answer to why it is implemented the way it is for List .该帖子很好地回答了为什么它以List的方式实现。

My question is:我的问题是:

  • Why is Alternative implemented for List at all?为什么要为List实施Alternative

Is there perhaps an algorithm that uses Alternative and a List might be passed to it so define it to hold generality?是否有可能使用Alternative的算法并且可以将List传递给它以便定义它以保持通用性?

I thought because Alternative by default defines some and many , that may be part of it but What are some and many useful for contains the comment:我想是因为Alternative默认定义了somemany ,这可能是其中的一部分,但是What are some and many 有用的包含评论:

To clarify, the definitions of some and many for the most basic types such as [] and Maybe just loop.为了澄清, somemany最基本类型的定义,例如[]Maybe只是循环。 So although the definition of some and many for them is valid, it has no meaning.因此,虽然somemany的定义对他们来说是有效的,但它没有任何意义。

In the "What are some and many useful for" link above, Will gives an answer to the OP that may contain the answer to my question, but at this point in my Haskelling, the forest is a bit thick to see the trees.在上面的“什么是一些有用的”链接中,Will 对可能包含我的问题的答案的 OP 给出了答案,但是在我的 Haskelling 中,森林有点厚,看不到树木。

Thanks谢谢

There's something of a convention in the Haskell library ecology that if a thing can be an instance of a class, then it should be an instance of the class. Haskell 库生态中有一个约定,如果一个事物可以是 class 的实例,那么它应该是 class 的实例。 I suspect the honest answer to "why is [] an Alternative ?"我怀疑对“为什么[]Alternative ?”的诚实回答。 is "because it can be".是“因为它可以”。

...okay, but why does that convention exist? ...好的,但是为什么存在该约定? The short answer there is that instances are sort of the one part of Haskell that succumbs only to whole-program analysis.简短的回答是,实例是 Haskell 的一部分,它只屈服于整个程序分析。 They are global, and if there are two parts of the program that both try to make a particular class/type pairing, that conflict prevents the program from working right.它们是全局的,如果程序的两个部分都试图进行特定的类/类型配对,那么这种冲突会阻止程序正常工作。 To deal with that, there's a rule of thumb that any instance you write should live in the same module either as the class it's associated with or as the type it's associated with.为了解决这个问题,有一个经验法则,即您编写的任何实例都应该与它关联的 class 或与其关联的类型存在于同一模块中。

Since instances are expected to live in specific modules, it's polite to define those instances whenever you can -- since it's not really reasonable for another library to try to fix up the fact that you haven't provided the instance.由于实例应该存在于特定模块中,因此尽可能定义这些实例是有礼貌的——因为另一个库试图修复您没有提供实例的事实是不合理的。

Consider a function like this:考虑这样的 function:

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

Not spectacularly meaningful, but you can imagine it being used in, say, a parser: try one thing, falling back to another if that doesn't work.意义不大,但您可以想象它被用于解析器:尝试一件事,如果不起作用,则退回到另一件事。

Does this function have a meaning when f ~ [] ?这个 function 在f ~ []时是否有意义? Sure, why not.当然,为什么不呢。 If you think of a list's "effects" as being a search through some space, this function seems to represent some kind of biased choice, where you prefer the first option to the second, and while you're willing to try either, you also tag which way you went.如果您将列表的“效果”视为对某个空间的搜索,那么这个 function 似乎代表了某种有偏见的选择,您更喜欢第一个选项而不是第二个选项,虽然您愿意尝试任何一个,但您也标记你走了哪条路。

Could a function like this be part of some algorithm which is polymorphic in the Alternative it computes in?像这样的 function 是否可以成为某些算法的一部分,该算法在它计算的替代方案中是多态的? Again I don't see why not.我不明白为什么不这样做。 It doesn't seem unreasonable for [] to have an Alternative instance, since there is an implementation that satisfies the Alternative laws. []有一个 Alternative 实例似乎不是不合理的,因为有一个满足 Alternative 法律的实现。

As to the answer linked to by Will Ness that you pointed out: it covers that some and many don't "just loop" for lists.至于您指出的 Will Ness 所链接的答案:它涵盖了somemany“只是循环”列表。 They loop for non-empty lists.它们循环查找非空列表。 For empty lists, they immediately return a value.对于空列表,它们会立即返回一个值。 How useful is this?这有多大用处? Probably not very, I must admit.可能不是很,我必须承认。 But that functionality comes along with (<|>) and empty , which can be useful.但是该功能伴随着(<|>)empty ,这可能很有用。

Alternative is useful when viewing [] as the nondeterminism-monad.当将[]视为非确定性单子时,替代方案很有用。 In that case, <|> represents a choice between two programs and empty represents "no valid choice".在这种情况下, <|>表示两个程序之间的选择,而empty表示“没有有效的选择”。 This is the same interpretation as for eg parsers.这与解析器的解释相同。

some and many does indeed not make sense for lists, since they try iterating through all possible lists of elements from the given options greedily, starting from the infinite list of just the first option. somemany对于列表确实没有意义,因为它们尝试从给定选项的所有可能元素列表中贪婪地迭代,从第一个选项的无限列表开始。 The list monad isn't lazy enough to do even that, since it might always need to abort if it was given an empty list. list monad 也懒得去做,因为如果给它一个空列表,它可能总是需要中止。 There is however one case when both terminates: When given an empty list.然而,当两者都终止时,有一种情况:当给定一个空列表时。

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

If some and many were defined as lazy (in the regex sense), meaning they prefer short lists, you would get out results, but not very useful, since it starts by generating all the infinite number of lists with just the first option:如果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,"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM