为什么在haskell中可以定义没有参数的函数
我有一个函数add,我部分应用它来创建一个新的函数addOne为什么在haskell中可以定义没有参数的函数,haskell,functional-programming,partial-application,Haskell,Functional Programming,Partial Application,我有一个函数add,我部分应用它来创建一个新的函数addOne add :: Int -> (Int -> Int) add x y = x + y 可以使用显式参数定义addOne addOne :: Int -> Int addOne y = add 1 y addOne :: Int -> Int addOne = add 1 或无显式参数 addOne :: Int -> Int addOne y = add 1 y addOne :: Int -&
add :: Int -> (Int -> Int)
add x y = x + y
可以使用显式参数定义addOne
addOne :: Int -> Int
addOne y = add 1 y
addOne :: Int -> Int
addOne = add 1
或无显式参数
addOne :: Int -> Int
addOne y = add 1 y
addOne :: Int -> Int
addOne = add 1
我有四个问题:
addOne y=add1y
意味着addOne=\y->add1y
,而\x->fx
总是f
。这被称为eta等价。所以addOne=add1
add :: Int -> Int -> Int
add = \x y -> x + y
是否可以完全删除变量绑定是另一回事在函数式编程中,使用Haskell需要学习的一个基本概念是函数只是一种值,定义只是命名。它不像过程语言那样在函数和变量之间有着明显的区别,函数定义与变量定义完全不同 所以一个变量定义如下
addOne :: Int -> Int
addOne = add 1
只是为表达式添加了一个名称add1
,因此您可以将其称为addOne
。这与变量声明相同。[1]从Haskell的角度来看,该变量的值是一个函数这一事实几乎是偶然的
您的添加定义:
add :: Int -> (Int -> Int)
add x y = x + y
也是一个变量定义。这是sugar Haskell提供的一点语法:
add :: Int -> Int -> Int
add = \ x -> \ y -> x + y
基于更容易阅读的理论。但它仍然只是糖;您永远不会像在其他语言中一样需要它(请参见下面的[1])
[1] 当前位置在这里也起作用。其思想是:在函数定义中,RHS将由计算机执行多次(调用函数的次数)。您可能从其他语言中了解到这一点。在单态变量定义中,RHS最多执行一次,这与其他语言的工作方式类似。然而,多态变量最终的作用通常类似于函数定义,RHS的执行次数与访问变量值的次数相同。所以Haskell dis允许多态定义,除非你有一个多态类型签名(所以你说“我知道我在做什么,允许这个变量是多态的”)或者你在左边有参数(所以“看起来”RHS应该执行很多次)您应该查看CurrId函数和部分应用程序:考虑案例<代码> StrcI::INT--> String > String < /Cord>;code>strTake=take
。所有这些都是为take
创建一个别名,它只在String
s上工作,而不是在任何类型的列表上工作。您不需要定义参数,只需将一个值设置为另一个值。然后,你可以考虑一些类似的东西:<代码> to5::[a] -> [a] < /代码>;code>take5=take5
。还有一个教程:还要注意,因为->
是右关联的,Int->(Int->Int)
与Int->Int
相同。与其他一些语言不同,Haskell中的这两种类型没有区别。正如其他人所指出的,无论您是否将函数实现为显式lambda,有时都会对优化或单态限制产生影响。我要补充的是,一些编辑器支持集成,这非常有助于告诉您何时可以减少,省去了您自己查找所有这些实例的麻烦。第二,hlint
非常适合这样做。这很有趣!至于问题2,GHC优化器有一个区别,但这可能是我们不应该在这里混淆人们的东西。