Haskell中的函数减少如何工作?

Man*_*kas 6 haskell functional-programming

为什么在Haskell中减少函数是可能的:

calculate :: Integer -> Integer -> Integer
calculate a b = f 1 a b
  where
     f :: Integer -> Integer -> Integer -> Integer
     f a b c = a + b
Run Code Online (Sandbox Code Playgroud)

进入某事:

calculate :: Integer -> Integer -> Integer
calculate = f 1
  where
     f :: Integer -> Integer -> Integer -> Integer
     f a b c = a + b
Run Code Online (Sandbox Code Playgroud)

我只需要一些指导,任何我可以找到答案的资源,阅读更多有关它的内容真的很有用.

Wil*_*sem 8

在Haskell中,没有函数可以使用多个参数.所有函数都正好一个参数.

所以,如果你有一个像这样的函数add :: Int -> Int -> Int,那么这实际上是很短的add :: Int -> (Int -> Int).

为什么括号重要?因为他们展示了这个概念的运作方式 如果我们有这个函数add,那么我们可以创建一个函数应用程序14,然后我们构造一个函数,如:

add14 :: Int -> Int
add14 = add 14
Run Code Online (Sandbox Code Playgroud)

所以这意味着我们现在有一个函数再次接受一个参数(这里是一个Int),现在它将生成另一个参数Int,它通过向它添加14来实现,因此add14 25将导致39.

如果你写add 14 25,那么这不是一个带有两个参数的函数应用程序,你实际写的是:

-- add 14 25 is equivalent to
(add 14) 25
Run Code Online (Sandbox Code Playgroud)

因此,您首先使用14,并使用由此产生的函数进行调用,并25作为参数进行调用.

为什么这很重要?因为这意味着如果你这样写

calculate = f 1
Run Code Online (Sandbox Code Playgroud)

它意味着你f 1构建一个函数,一个带签名的函数Int -> (Int -> Int).因此,在头部创建参数calculate并将这些参数添加到末尾是f 1没有意义的:您已经构建了一个无论如何都需要这些参数的函数.所以它只会引入噪音.

lambda演算中,重写规则,其中一个重写λx.fxf是(反之亦然)被称为η-转换 [wiki].在Haskell中,它归结为重写:

f x = g x
Run Code Online (Sandbox Code Playgroud)

至:

f = g
Run Code Online (Sandbox Code Playgroud)

运营商也不例外.事实上,如果你a + b在Haskell中编写,你(+) a b(+)函数编写,或者更详细((+) a) b.

fwhere子句中:

f a b c = a + b
Run Code Online (Sandbox Code Playgroud)

例如可以转换为:

f = (.) ((.) const) (+)
Run Code Online (Sandbox Code Playgroud)