You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何用foldr实现map'时出现类型不匹配错误?

用foldr实现map时的错误原因与修复方案

首先来看你碰到的错误提示:

test.hs:2:13: error:
• 无法匹配预期类型‘[b]’与实际类型‘t0 a -> [b]’
• 可能原因:‘foldr’被应用的参数过少
在表达式:foldr (\ x acc -> f x : acc) []
在‘map'’的定义中:map' f xs = foldr (\x acc -> f x : acc) []
• 相关绑定包括:
xs :: [a](绑定于test.hs:2:8)
f :: a -> b(绑定于test.hs:2:6)
map' :: (a -> b) -> [a] -> [b](绑定于test.hs:2:1)
| 2 | map' f xs = foldr (\x acc -> f x : acc) []
| ^^^^^^^^^^^^^^^^^^^^^^^^^

错误核心:foldr的参数传少了

Haskell里foldr的类型签名是这样的:

foldr :: (a -> b -> b) -> b -> [a] -> b

它需要三个参数才能返回最终结果:

  • 第一个是折叠逻辑函数:负责处理当前元素和累积的结果
  • 第二个是初始累积值
  • 第三个是要被折叠的目标列表

你写的代码里,只给了foldr前两个参数(lambda函数和空列表[]),但漏掉了关键的第三个参数xs!这时候foldr不会直接生成[b]类型的列表,而是返回一个还在等待接收列表参数的函数(类型是[a] -> [b]),但你的map'函数声明要返回的是[b],类型自然就对不上了,编译器也就抛出了这个类型不匹配的错误。

修复后的正确代码

只需要把xs传给foldr就行,补上第三个参数:

map' :: (a -> b) -> [a] -> [b]
map' f xs = foldr (\x acc -> f x : acc) [] xs

再唠两句实现逻辑

这个lambda函数\x acc -> f x : acc的作用很直观:每次拿到列表里的当前元素x,先用f把它转换成目标类型,再把转换后的结果加到累积列表acc的前面。初始值是空列表[],当foldr遍历完整个xs后,就自然得到了所有元素都被f转换后的新列表,完全符合map的功能~

内容的提问来源于stack exchange,提问作者Shaurya Gupta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:10:16