为什么Haskell优先级只有10个级别?10的数字够了吗?

Nik*_*mar 11 haskell operator-precedence

我想知道为什么Haskell设计师同意只允许10个级别的优先级?有人发现它不够吗?

C. *_*ann 21

据我所知,它完全是武断的.我所知道的所有文档都只是将其描述为事实,没有任何详细说明或理由.

但如果你考虑一下,为什么还有其他更好的东西呢?好吧,让我们说10还不够.你有(.)哪个具有最高的固定性,你想要一些更紧密的东西.您添加了一个额外的级别,因此您的新最大值为10(即使大多数固定级别仅为9).

现在你有11个级别的优先级.(这太荒谬了.它甚至都不好笑.)这比10更不随意吗?什么阻止你添加更多?如果您想要现有的新级别怎么办?当然,你可以继续增加更多,直到最终你发现自己写作infix? (? + 2i)并想知道你的生活出了什么问题.

问题是,运算符优先级本质上是一个非常随意的事情.有一些约定 - 乘法事物比加法事物更紧密,逻辑运算符的优先级低于布尔值函数,例如 - (==)但这些有些限制,通常不会覆盖多个级别.否则,记住运算符优先级的唯一方法是......好吧,记住它们,就像简单地记住每一个一样.这不仅是一件苦差事,它还可能使代码对于那些可能没有记忆的人也不透明.人工记忆是一种非常有限的资源,因此编码时需要回忆的挑剔细节越少越好.

Haskell中运算符的大多数用法,其中优先级问题属于几个粗略组中的一个:

  • 伪合成运算符,如常用($),通常需要极高或极低的优先级,以避免与其他运算符冲突.

  • 使用标准运算符或其变体的表达式,其中存在少数标准优先级,并且新运算符通常应该与它们所基于的任何级别共享相同的级别.

  • 专用运算符集,例如EDSL,其符号和优先级通常被选择以反映EDSL的性质,并且不可能与其他运算符集共存.

只有少数优先级,所有这些都可以很好地管理.更重要的是,它们的特点是要么有效地独立于其他运营商,要么仅与非常有限的其他运营商一起使用.开始添加更多的运算符并将它们混合在一起表达,很快人们就会开始使用明确的括号,因为他们不记得什么比什么绑定更紧密.说到我自己,在将EDSL风格的运算符(比如Arrow组合器)与逻辑运算符混合时,我已经倾向于明确括号,因为我通常无法回想起每个运算符的确切优先级.

所以,已经确定:1)许多额外的优先级别不会那么有用,因为它太过于无法跟踪,2)我们选择的任何限制都将是同样的任意...为什么10?我猜测"因为那时固定值只是一位数".

  • 很好的答案("特别想知道你的生活出了什么问题"),但我认为你应该至少攻击一个Spinal Tap参考. (3认同)
  • @mu太短了啊:那就是"大多数固定只有9".:)尽管如此,大多数放大器都会达到10,因为摇滚音乐家倾向于从1开始计数,而不是0.但是范围相当.(实际上,该段中的很多措辞都是模仿Spinal Tap的线条,但那更加微妙) (2认同)

aug*_*tss 8

级别的数量是任意的,并且我记得决定是很多级别只是让人难以记住操作符的交互方式.例如Prolog允许1000级,但我从未发现它比Haskell好得多.

扩展Haskell优先级,您可以想象将其更改为有理数,这样您就可以始终在两个现有运算符之间调整运算符.但更好的选择可能是切换到优先级为部分订单.所以给两个操作员他们可以相关,然后相应地处理,或者不相关会强制括号.