输入以下内容时,我对理解编译器的功能存在疑问:

(curry . uncurry) (+) 1 2
在我理解之后,编译器首先使用uncurry,这将意味着会发生错误,因为uncurry函数需要这样的输入:
(curry . uncurry) (+) (1,2)
但显然第一个是对的。我不明白为什么。
编译器对此进行评估时究竟采取了哪些步骤?
另一个主题包括以下问题:
为什么
(uncurry . curry) (+) (1,2)
不起作用?

最佳答案


不,它与(curry . uncurry)一起使用
如果我们评估(curry . uncurry)函数,我们将看到以下简称:

\x -> curry (uncurry x)
因此(curry . uncurry) (+) 1 2函数的缩写为:
(\x -> curry (uncurry x)) (+) 1 2
或因此:
(curry (uncurry (+))) 1 2
uncurry :: (a -> b -> c) -> (a, b) -> c curry :: ((a, b) -> c) -> a -> b -> c 从而转换一个函数。因此,这意味着uncurry (+)实际上期望一个2元组:
uncurry (+) :: Num a => (a, a) -> a
但现在通过curry函数传递此函数:
curry (uncurry (+)) :: Num a => a -> a -> a
因此curry函数撤消了将uncurry转换为(+)函数的转换。因此,这意味着curry (uncurry (+))(+)相同,因此:
(curry (uncurry (+))) 1 2
等效于:
(+) 1 2
因此,这等效于3curry . uncurry并不完全等同于id,因为它具有以下类型:
curry . uncurry :: (a -> b -> c) -> a -> b -> c
因此,这意味着它将功能限制为a -> (b -> c)类型的功能。

09-05 19:58