简体   繁体   English

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

[英]How function reduction in Haskell works?

Why it's possible to reduce function in Haskell: 为什么在Haskell中减少函数是可能的:

calculate :: Integer -> Integer -> Integer
calculate a b = f 1 a b
  where
     f :: Integer -> Integer -> Integer -> Integer
     f a b c = a + b

into something: 进入某事:

calculate :: Integer -> Integer -> Integer
calculate = f 1
  where
     f :: Integer -> Integer -> Integer -> Integer
     f a b c = a + b

I just need some guidance, any resources where I can find the answer and read more about it would be really helpful. 我只需要一些指导,任何我可以找到答案的资源,阅读更多有关它的信息会非常有用。

In Haskell there are no functions that take more than one parameter. 在Haskell中, 没有函数可以使用多个参数。 All functions take exactly one parameter. 所有函数都只有一个参数。

So if you have a function like add :: Int -> Int -> Int , then this is actually short for add :: Int -> (Int -> Int) . 因此,如果你有一个像add :: Int -> Int -> Int这样的函数,那么这实际上是add :: Int -> (Int -> Int)缩写。

Why are the brackets important? 为什么括号重要? Because they show how this concept works. 因为他们展示了这个概念的运作方式 If we have this function add , then we can make a function application with for example 14 , then we construct a new function, like: 如果我们有这个函数add ,那么我们可以用例如14创建一个函数应用程序,然后我们构造一个函数,如:

add14 :: Int -> Int
add14 = add 14

so that means that we now have a function that takes again one parameter (here an Int ), and now it will produce another Int , it does that by adding 14 to it, so add14 25 will result in 39 . 所以这意味着我们现在有一个函数再次获取一个参数(这里是一个Int ),现在它将生成另一个Int ,它通过向它添加14来实现,所以add14 25将导致39

If you write add 14 25 , this thus is not a function application with two parameters, what you actually wrote is: 如果你编写add 14 25 ,那么这不是一个带有两个参数的函数应用程序,你实际写的是:

-- add 14 25 is equivalent to
(add 14) 25

You thus first make a call with 14 , and the you make a call with the function that comes out of this, and 25 as the parameter. 因此,您首先使用14进行调用,然后使用由此产生的函数调用,并将25作为参数。

Why is this important? 为什么这很重要? Because it means that if you thus write 因为这意味着如果你这样写

calculate = f 1

it means that your f 1 , constructs a function, a function with signature Int -> (Int -> Int) . 它意味着你的f 1 ,构造一个函数,一个带有签名Int -> (Int -> Int)的函数。 Creating parameters in the head of calculate , and adding these to the end of f 1 , thus makes no sense: you already constructed a function that takes such parameters anyway. calculate头中创建参数,并将这些参数添加到f 1的末尾,这是没有意义的:你已经构建了一个无论如何都需要这些参数的函数。 So it only introduces noise. 所以它只会引入噪音。

In lambda calculus , the rewrite rule where one rewrites λ x . lambda演算中 ,重写规则,其中一个重写λx。 fx to just f is (and vice versa) is called η-conversion [wiki] . fxf是(反之亦然)被称为η-转换 [wiki] In Haskell it comes down to rewriting: 在Haskell中,它归结为重写:

f x = g x

to: 至:

f = g

Operators are no different. 运营商也不例外。 In fact if you write a + b in Haskell, you wrote (+) ab , with (+) a function, or more verbose ((+) a) b . 事实上,如果你在Haskell中写a + b ,你写(+) ab ,用(+)一个函数,或者更详细((+) a) b

The f in the where clause: where子句中的f

f a b c = a + b

can for example get converted to: 例如可以转换为:

f = (.) ((.) const) (+)

It's called eta reduction . 它被称为eta 减少

You might also think about it in terms of partial application. 您也可以考虑部分应用。

> calculate :: Integer -> Integer -> Integer
> f :: Integer -> Integer -> Integer -> Integer
> (f 1) :: Integer -> Integer -> Integer

Similar question - What does eta reduce mean in the context of HLint 类似的问题 - 在HLint的背景下,eta减少了什么意思

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM