Rom*_*man 1 syntax haskell functional-programming add
在Codefights挑战中你必须添加两个数字,用户kaiochao有一个超级简约的答案
add = (+)
Run Code Online (Sandbox Code Playgroud)
它是如何工作的,并且具有自己的名称?
这是一个明确的定义:
add a b = a + b
Run Code Online (Sandbox Code Playgroud)
Haskell中有一个功能,即我们可以重写a + b为(+) a b,这是因为运算符是Haskell中的函数.所以我们可以改写:
add a b = (+) a b
Run Code Online (Sandbox Code Playgroud)
但是我们对这个函数的参数没有做任何额外的事情,所以我们可以通过删除显式参数*来减少这个函数.请注意,这需要了解Haskell中的函数应用程序如何工作:
add = (+)
Run Code Online (Sandbox Code Playgroud)
这是因为函数是Haskell中的数据.这实际上是说plus和添加的功能是一回事.
在实践中,我们可以通过替换来看到:
add 1 2
= (+) 1 2 -- Since add = (+), this can be read literally.
= 1 + 2 -- This is how operators work in Haskell.
= 3 -- Calculation.
Run Code Online (Sandbox Code Playgroud)
这在Haskell中被称为pointfree样式.
*正如@Benjamin Hodgson所提到的,这被称为eta-reduction.
这个"功能"只是变量赋值.它的工作方式与写作相同
three = 3
Run Code Online (Sandbox Code Playgroud)
3只是一个Haskell值,我可以在任何时候给出一个新名称,引用它,并得到一些(至少在运行时)与3它自己无法区分的东西.
add具有更复杂类型的事实,即函数类型,对这种变量赋值的工作方式没有任何改变.我当然可以定义
root = sqrt
Run Code Online (Sandbox Code Playgroud)
...然后评估root 4以获得2.0结果.或者,对于任何自定义功能,
foo :: Int -> String
foo n = concat $ replicate n (show n)
bar = foo
GHCi> bar 3
"333"
GHCi> bar 7
"7777777"
Run Code Online (Sandbox Code Playgroud)
所有这些与我也可以写的完全没有什么不同
Python 3.5.2 (default, Sep 14 2017, 22:51:06)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import math
In [2]: root = math.sqrt
In [3]: root(4)
Out[3]: 2.0
Run Code Online (Sandbox Code Playgroud)
更有趣的add是,它+是一个中缀运算符(因为它由非字母字符组成).但是Haskell允许使用这样的中缀运算符,就像任何其他变量一样,包括你可以定义自己的变量.唯一不同的是解析规则.+不能是一个独立的语法单元,但必须在每一侧都包含你想要添加的参数,或括号.后者(+),是真的什么加运营商但从编译器的点:二元函数,不是还没有应用到任何参数.因此,当您想要为此运算符指定新名称时,您需要编写
add = (+)
Run Code Online (Sandbox Code Playgroud)
顺便说一下,你也可以给它一个新的运算符名称,比如
(?) = (+)
Run Code Online (Sandbox Code Playgroud)
......然后可以像3 ? 4标准+操作员一样使用.