Haskell 柯里化
Haskell Currying
在过去的两个小时里,我一直在阅读 Haskell 中有关柯里化的内容,所有资源都展示了具有多个参数的函数实际上如何 return 其他函数,但没有介绍它们的定义,所以这就是问题所在。
让我们定义函数:
myFunc :: (Num a) => a -> a -> a
myFunc x y = x * 2 + x * y
:t (myFunc 2)
打印 Num a => a -> a
,即一个接受数字并输出数字的函数。但是,(myFunc 2)
编辑的函数 return 的定义是什么样的?编译器是否在定义中替换 x
并且新函数变成类似 myFunc' y = 2 * 2 + 2 * y
?
递归如何处理柯里化?如果我定义函数
replicate' :: (Integral i, Ord i) => i -> a -> [a]
replicate' n x
| n <= 0 = []
| otherwise = x : replicate' (n - 1) x
,在上下文 (replicate 3) 'a'
中由 (replicate' 3)
编辑的函数 return 是什么?
我认为你混淆了两种不同的东西
- 柯里化
- 部分功能应用
第一个是
------currying----->
f :: (a,b) -> c f' :: a -> b -> c
<----uncurrying-----
将一个接受 元组 个参数的函数转换为一个接受一个参数并生成一个函数的函数!
如果您熟悉线性代数,这与将双线性函数视为产生另一个线性函数的线性函数非常相似。
而部分函数应用只是显式括号化的结果。
f :: a -> b -> c
真的
f :: a -> (b -> c)
至少在 haskell 定义函数的方式中。
这是 replicate'
以显式柯里化形式定义的:
replicate' :: (Integral i, Ord i) => i -> (a -> [a])
replicate' n
| n <= 0 = const []
| otherwise = \x -> x : replicate' (n - 1) x
那么,replicate' 3
的计算结果为表达式
if 3 <= 0 then const []
else \x -> x : replicate' 2 x
也就是
\x -> x : replicate' 2 x
如果它只是用“隐式柯里化”定义的,那么编译器可能会也可能不会从 x
绑定中提取 n <= 0
条件,所以实际上你可能只会得到
\x -> if 3 <= 0 then const []
else \x -> x : replicate' 2 x
在过去的两个小时里,我一直在阅读 Haskell 中有关柯里化的内容,所有资源都展示了具有多个参数的函数实际上如何 return 其他函数,但没有介绍它们的定义,所以这就是问题所在。
让我们定义函数:
myFunc :: (Num a) => a -> a -> a
myFunc x y = x * 2 + x * y
:t (myFunc 2)
打印 Num a => a -> a
,即一个接受数字并输出数字的函数。但是,(myFunc 2)
编辑的函数 return 的定义是什么样的?编译器是否在定义中替换 x
并且新函数变成类似 myFunc' y = 2 * 2 + 2 * y
?
递归如何处理柯里化?如果我定义函数
replicate' :: (Integral i, Ord i) => i -> a -> [a]
replicate' n x
| n <= 0 = []
| otherwise = x : replicate' (n - 1) x
,在上下文 (replicate 3) 'a'
中由 (replicate' 3)
编辑的函数 return 是什么?
我认为你混淆了两种不同的东西
- 柯里化
- 部分功能应用
第一个是
------currying----->
f :: (a,b) -> c f' :: a -> b -> c
<----uncurrying-----
将一个接受 元组 个参数的函数转换为一个接受一个参数并生成一个函数的函数!
如果您熟悉线性代数,这与将双线性函数视为产生另一个线性函数的线性函数非常相似。
而部分函数应用只是显式括号化的结果。
f :: a -> b -> c
真的
f :: a -> (b -> c)
至少在 haskell 定义函数的方式中。
这是 replicate'
以显式柯里化形式定义的:
replicate' :: (Integral i, Ord i) => i -> (a -> [a])
replicate' n
| n <= 0 = const []
| otherwise = \x -> x : replicate' (n - 1) x
那么,replicate' 3
的计算结果为表达式
if 3 <= 0 then const []
else \x -> x : replicate' 2 x
也就是
\x -> x : replicate' 2 x
如果它只是用“隐式柯里化”定义的,那么编译器可能会也可能不会从 x
绑定中提取 n <= 0
条件,所以实际上你可能只会得到
\x -> if 3 <= 0 then const []
else \x -> x : replicate' 2 x