Haskell如何实现元组列表中指定两个元组的第二个元素交换
你的现有实现存在两个逻辑问题:
- 遍历过程中匹配失败时没有保留当前元组,导致所有未匹配的前置元素被直接丢弃
- 匹配到第一个目标后直接返回剩余列表,没有继续处理剩余列表中的第二个目标元素
修正实现
以下是和你原有递归思路对齐的修改版本:
swapper :: (Eq a, Eq b) => a -> b -> b -> [(a,b)] -> [(a,b)] swapper _ _ _ [] = [] swapper x y z ((a,b):xs) | x == a = (a, z) : swapper x y z xs | b == z = (a, y) : swapper x y z xs | otherwise = (a, b) : swapper x y z xs
如果偏好高阶函数写法,也可以用map实现更简洁的版本:
swapper :: (Eq a, Eq b) => a -> b -> b -> [(a,b)] -> [(a,b)] swapper x y z = map (\pair@(a, b) -> case () of _ | a == x -> (a, z) | b == z -> (a, y) | otherwise -> pair)
调用说明
针对你的场景,调用swapper S (Just 8) Nothing b就可以得到预期输出:所有非目标元素保持不变,S对应的元组第二个元素替换为Nothing,SE对应的元组第二个元素替换为Just 8。
你之前提到的直接写z == Nothing报错的问题,通过将Nothing作为入参传入即可规避,因为此时z的类型和列表中元组的第二个元素类型完全对齐,自动满足Eq约束。
内容的提问来源于stack exchange,提问作者Jaffa
相关产品推荐
相关产品推荐

