首页 > 解决方案 > 无法理解以未部分应用函数作为参数提供的高阶函数调用的结果

问题描述

我有一个高阶函数声明来应用作为参数给出的函数两次:

twice :: (a -> a) -> a -> a
twice f x = f (f x)

困惑来自这个 GHCi 会议:

*Main> let _4 = twice twice
*Main> let __4 = twice twice (*2)
*Main> let _16 = _4 _4
*Main> let __16 = _4 __4
*Main> _16 (*2) 2
231584178474632390847141970017375815706539969331281128078915168015826259279872
*Main> __16 2
131072

有点清楚__16,因为正在发生的只是这个函数调用的“乘法”,所以我们实际上会(2 ^ 16) * 2在它调用之后得到。据我所知,这是因为作为参数给出的函数已经部分应用,所以 __4 和 __16 的类型是(Num a) => a -> a.

但是_16使用给定函数和整数参数调用的结果只会让我感到困惑。我可以理解两者的类型_4都是_16原始的(等于twice函数的签名,但嵌套在引擎盖下),但它让我不知道为什么结果差异如此之大。在提供了一个未部分用作参数的函数后,我无法获得程序的语义。有人可以解释一下为什么这个数字这么棒吗?

标签: haskellfunctional-programmingcurryingpartial-application

解决方案


使用 Church 数字,两个数字的应用a b相当于指数b^a。所以,_4 _4对应于4^4=256,而不是16

大致:_4 f意思是f . f . f . f,即“做f四次,或“乘以f四”。所以,_4 _4 f意思是“乘以f四,四次”,因此4^4

确实:

> 2^256 * 2 :: Integer
231584178474632390847141970017375815706539969331281128078915168015826259279872

推荐阅读