haskell - 无法理解以未部分应用函数作为参数提供的高阶函数调用的结果
问题描述
我有一个高阶函数声明来应用作为参数给出的函数两次:
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
函数的签名,但嵌套在引擎盖下),但它让我不知道为什么结果差异如此之大。在提供了一个未部分用作参数的函数后,我无法获得程序的语义。有人可以解释一下为什么这个数字这么棒吗?
解决方案
使用 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
推荐阅读
- ios - 如何在 XCUITest 中访问 iOS 14 时间选择器
- java - 运行所有测试用例时,我的测试用例失败。但是单独跑的时候通过
- python - 如何动态生成外部 CSS?
- php - PHP 警告:mysqli_stmt_bind_param():类型定义字符串中的元素数与绑定变量数不匹配
- swift - Parse Server Swift Logic 用于抓取数组中包含的所有项目
- c# - 谁能解释 C# 8.0 中的默认接口实现是什么?
- r - 如何轻松地对数据框中的特定数据进行子集化?
- python - Python函数不改变变量
- c++ - C++,将整数字节打包成一个字符数组?
- php - 为什么使用数组推送不附加到 PHP 中的关联数组