虽然我学习 Haskell 一段时间了,但我经常遇到一个常见问题。我们以这个表达式为例:
e f $ g . h i . j
有人可能想知道,鉴于 Prelude 中的 $
和 .
,e
或 h
上的类型约束是什么表达式是否有效?
是否有可能获得“更简单”但等效的表示形式?对我来说,“更简单”是指在任何地方都使用括号,并且无需定义运算符优先级规则。
如果没有,我需要阅读 Haskell 报告的哪些部分才能获得完整的了解?
这可能与许多 Haskell 程序员新手相关。我知道许多程序员添加括号,这样他们就不需要记住(或理解)像这样的优先级表:http://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
最佳答案
是否有可能获得“更简单”但等效的表示形式?当然,这就是所谓的解析,是由编译器、解释器等来完成的。
90% 的情况下,您需要记住的只是 $
、 .
和函数应用程序 f x
如何协同工作。这是因为 $
和函数应用非常简单 - 它们分别绑定(bind)最松和最紧 - 它们就像 bodmas 中的加法和指数。 .
从你的例子
e f $ g . h i . j
函数应用程序首先绑定(bind),所以我们有
(e f) $ g . (h i) . j
函数应用程序是左关联的
f g h ==> ((f g) h)
您可能需要通过谷歌柯里化(Currying)来理解为什么上面的内容可以像其他语言中的 foo(a, b)
一样使用。
在下一步中,完成中间的所有操作 - 我只是使用括号或表格来记住这一点,这通常很简单。例如,当您使用 monad 时,会同时使用多个运算符,例如 >>
和 >>=
。我只是在 ghc 提示时添加括号。
所以我们没有
(e f) $ (g . ((h i) . j))
括号的顺序并不重要,因为 function composition是结合律,但 Haskell 使其成为右结合律。
那么我们就有了
((e f) (g . ((h i) . j)))
上面的(简单)示例演示了为什么这些运算符首先存在。
关于haskell - 如何获得更简单但等效的 Haskell 表达式版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20300844/