Haskell如何实现更新元组列表中指定key对应值的函数?
错误原因
- 边界条件逻辑错误:输入为空列表时,你当前的实现会返回仅包含传入键值对的列表,不符合「仅替换列表中已有匹配key」的需求,空输入应该返回空列表。
map调用参数缺失:map的类型为(a -> b) -> [a] -> [b],需要同时传入转换函数和待处理的列表两个参数,你仅传入了转换函数,没有传入待遍历的元组列表,因此触发类型错误。- 额外冗余的列表拆分:你不需要手动拆分列表为
(x:xs),map本身会自动完成整个列表的遍历处理。
修正后的实现(基于map)
changeTup :: (Eq a) => (a,b) -> [(a,b)] -> [(a,b)] changeTup (y,z) lst = map replace lst where replace (key, value) | y == key = (key, z) | otherwise = (key, value)
利用Haskell的柯里化特性,也可以简化为隐式传参的写法:
changeTup :: (Eq a) => (a,b) -> [(a,b)] -> [(a,b)] changeTup (y,z) = map replace where replace (key, value) | y == key = (key, z) | otherwise = (key, value)
纯递归实现(不使用map)
如果你需要手写递归逻辑而非借助高阶函数map,可以参考如下写法:
changeTup :: (Eq a) => (a,b) -> [(a,b)] -> [(a,b)] changeTup _ [] = [] changeTup (y,z) ((k,v):xs) | y == k = (k, z) : changeTup (y,z) xs | otherwise = (k, v) : changeTup (y,z) xs
测试验证
执行changeTup (1, "Hello") [(1, "One"), (2, "Two")]即可得到预期输出[(1,"Hello"),(2,"Two")]。
内容的提问来源于stack exchange,提问作者CeilingSystems
相关产品推荐
相关产品推荐

