为何用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
相关产品推荐
相关产品推荐

