Haskell: Uncurry, Curry, 组合

fre*_*ist 5 haskell currying

当我输入以下内容时,我无法理解编译器的作用:

(curry . uncurry) (+) 1 2 
Run Code Online (Sandbox Code Playgroud)

在我理解之后,编译器首先使用 uncurry,这意味着会发生错误,因为 uncurry 函数需要这样的输入:

(curry . uncurry) (+) (1,2)
Run Code Online (Sandbox Code Playgroud)

但显然第一个是对的。我不明白为什么。

编译器在评估这个时到底采取了哪些步骤?

另一个主题包括问题:为什么

(uncurry . curry) (+) (1,2) 
Run Code Online (Sandbox Code Playgroud)

不起作用?

Wil*_*sem 7

在我理解之后,编译器采用了 uncurry。

不,它与 (curry . uncurry)

如果我们评估这个(curry . uncurry)函数,我们会看到它的缩写:

\x -> curry (uncurry x)
Run Code Online (Sandbox Code Playgroud)

所以这个(curry . uncurry) (+) 1 2函数的缩写是:

(\x -> curry (uncurry x)) (+) 1 2
Run Code Online (Sandbox Code Playgroud)

或因此:

(curry (uncurry (+))) 1 2
Run Code Online (Sandbox Code Playgroud)

uncurry :: (a -> b -> c) -> (a, b) -> ccurry :: ((a, b) -> c) -> a -> b -> c由此变换的功能。因此,这意味着uncurry (+)确实需要一个 2 元组:

uncurry (+) :: Num a => (a, a) -> a
Run Code Online (Sandbox Code Playgroud)

但现在通过函数传递这个curry函数:

curry (uncurry (+)) :: Num a => a -> a -> a
Run Code Online (Sandbox Code Playgroud)

所以curry函数撤销对函数uncurry所做的转换(+)。因此,这意味着curry (uncurry (+))与 相同(+),因此:

(curry (uncurry (+))) 1 2
Run Code Online (Sandbox Code Playgroud)

相当于:

(+) 1 2
Run Code Online (Sandbox Code Playgroud)

这因此等价于3

curry . uncurry不完全等同于id然而,由于它具有类型:

curry . uncurry :: (a -> b -> c) -> a -> b -> c
Run Code Online (Sandbox Code Playgroud)

因此,这意味着它将函数限制为类型为 的函数a -> (b -> c)