当我输入以下内容时,我无法理解编译器的作用:
(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)
不起作用?
在我理解之后,编译器采用了 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) -> c并curry :: ((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)。