haskell - 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
变成某事:
calculate :: Integer -> Integer -> Integer
calculate = f 1
where
f :: Integer -> Integer -> Integer -> Integer
f a b c = a + b
我只需要一些指导,任何可以找到答案并阅读更多相关信息的资源都会非常有帮助。
解决方案
在 Haskell 中,没有任何函数可以接受多个参数。所有函数都只接受一个参数。
所以如果你有一个类似的函数add :: Int -> Int -> Int
,那么这实际上是add :: Int -> (Int -> Int)
.
为什么括号很重要?因为他们展示了这个概念是如何运作的。如果我们有这个函数add
,那么我们可以用 example 做一个函数应用程序14
,然后我们构造一个新函数,比如:
add14 :: Int -> Int
add14 = add 14
所以这意味着我们现在有一个函数,它再次接受一个参数(这里是一个Int
),现在它会产生另一个Int
,它通过向它添加 14 来实现,所以add14 25
会产生39
.
如果您编写add 14 25
,则这不是具有两个参数的函数应用程序,您实际编写的是:
-- add 14 25 is equivalent to
(add 14) 25
因此,您首先使用 进行调用14
,然后使用由此产生的函数并25
作为参数进行调用。
为什么这很重要?因为这意味着如果你这样写
calculate = f 1
这意味着你的f 1
, 构造一个函数,一个带有签名的函数Int -> (Int -> Int)
。在 的头部创建参数calculate
,并将这些添加到 的末尾f 1
,因此没有意义:您已经构建了一个无论如何都接受这些参数的函数。所以它只会引入噪音。
在lambda 演算中,重写λ x 的重写规则。fx到f是(反之亦然)称为η-conversion [wiki]。在 Haskell 中,它归结为重写:
f x = g x
至:
f = g
运营商也不例外。事实上,如果你用a + b
Haskell 编写,你写的是(+) a b
, 带有(+)
一个函数,或者更详细((+) a) b
的 .
f
where 子句中的:
f a b c = a + b
例如可以转换为:
f = (.) ((.) const) (+)
推荐阅读
- css - 使用 CSS:如何对透明背景进行径向擦除过渡或动画
- oracle - 使用参数执行存储过程并在一个或另一个表上插入
- sql - 从 SQL 数据库中检索值 - EF
- angular - Angular 4路由到外部网址
- java - JpaRepository.findOne(long id) 不适用于 Spring 数据 jpa
- css - Flexbox Expandable Items in Row,停止行扩展
- php - 复杂的 PHP 数组搜索
- c# - 如何结合处理在网络流上使用 ReadAsync()?
- object - 我收到以下错误
- angular - 通过服务在组件之间共享数据在 Angular 6 中是只读的