haskell - foldr 类型签名与 foldl one 不同有什么原因吗?
问题描述
与 foldr 相比,我对 foldl 的定义有点困惑。Foldr 与 foldl 的不同不仅在于关联性,还在于折叠函数参数顺序:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldl :: (b -> a -> b) -> b -> [a] -> b
我看不出 foldl 不能这样定义的任何原因:
foldl :: (a -> b -> b) -> b -> [a] -> b
foldl f acc [] = acc
foldl f acc (x:xs) = foldl f (f x acc) xs
因此 foldl 可以应用于非交换折叠函数以及 foldr:
Prelude> foldr (:) [] [1..5]
[1,2,3,4,5]
Prelude> foldl (:) [] [1..5]
<interactive>:4:7: error:
<...>
Prelude> myfoldl (:) [] [1..5]
[5,4,3,2,1]
使用标准 foldl 定义,我们需要使用flip
来获得与使用相同的行为foldr
解决方案
您可以按该顺序获得以下不错的等式属性:
foldl (+) z [a, b, c] = (((z + a) + b) + c)
foldr (+) z [a, b, c] = a + (b + (c + z))
推荐阅读
- google-apps-script - 根据两个条件删除一行
- windows - 如何使用 hRawInput 将真实的键盘或鼠标输入与“SendInput”等命令输入区分开来
- ruby - 将文件传递给 ruby 程序时权限被拒绝
- sms - Android stock SMS App preview 在用户点击之前预取嵌入在文本消息中的链接?
- git - git --name-status 忽略所有空格
- r - 当函数需要多个输入时,如何将函数应用于 R 中数据帧的每一行?
- python - django-rest-registration 0.5.1 抛出 RESET_PASSWORD_VERIFICATION_URL 和 RESET_PASSWORD_VERIFICATION_URL 未设置,即使它们已设置
- python - 如何在 n 秒后停止等待用户输入数据?
- javascript - 完成 AWS 身份验证流程
- html - 如何在顶部而不是居中创建文本输入