如何获得更简单但相当于Haskell表达式的版本

Rum*_*mca 5 haskell

虽然我已经学习了Haskell一段时间,但我经常遇到一个常见的问题.我们以此表达式为例:

e f $ g . h i . j
Run Code Online (Sandbox Code Playgroud)

有人可能想知道,给出$.来自Prelude,什么是类型约束eh表达有效?

是否有可能获得"更简单"但等效的表示?对我来说,"更简单"将是一个在任何地方都使用括号的人,并且无需定义运算符优先级规则.

如果没有,我需要阅读哪些Haskell报告部分才能获得完整的图片?

这可能与许多新手Haskell程序员有关.我知道许多程序员添加括号,这样他们就不需要记住(或理解)像这样的优先级表:http://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

use*_*280 1

是否有可能获得“更简单”但等效的表示?当然,这称为解析,由编译器、解释器等完成。

90% 的时候,您需要记住的只是$.和函数应用程序f x如何协同工作。这是因为和 函数应用非常简单 - 它们分别绑定最松和最紧 - 它们就像bodmas$中的加法和指数。

从你的例子来看

e f $ g . h i . j
Run Code Online (Sandbox Code Playgroud)

函数应用程序首先绑定,所以我们有

(e f) $ g . (h i) . j
Run Code Online (Sandbox Code Playgroud)

函数应用程序是左关联的,因此

f g h ==> ((f g) h)
Run Code Online (Sandbox Code Playgroud)

您可能需要谷歌柯里化才能理解为什么上面的内容可以像foo(a, b)其他语言一样使用。

在下一步中,做中间的所有事情 - 我只是使用括号或表格来记住这一点,它通常很简单。例如,当您使用 monad 时,会同时使用多个运算符,例如>>>>=。当 ghc 抱怨时我只是添加括号。

所以不,我们有

(e f) $ (g . ((h i) . j))
Run Code Online (Sandbox Code Playgroud)

括号的顺序并不重要,因为函数组合是关联的,但 Haskell 使其成为右关联。

那么我们有

((e f) (g . ((h i) . j)))
Run Code Online (Sandbox Code Playgroud)

上面的(简单)示例演示了为什么这些运算符首先存在。