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)
我只需要一些指导,任何我可以找到答案的资源,阅读更多有关它的内容真的很有用.
在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.fx到f是(反之亦然)被称为η-转换 [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)