在元组列表中交换元组

时间:2014-12-09 16:59:23

标签: list haskell

我尝试编写一个能够在元组列表中交换元组的代码: [(" a"," b"),(" c"," d")] - > [(" B""&#34),(" d"" C&#34)]

tupleXTurn :: [(String,String)]->[(String,String)]
tupleXTurn (x:xs) = (snd x,fst x) ++ (tupleXTurn xs)

存在与这些类​​型相对应的错误。 非常感谢!

错误是:

Couldn't match type ‘xs’ with ‘String’
  ‘xs’ is a rigid type variable bound by
       an expression type signature: tupleXTurn xs
       at ZinkeMarencicUebung08.hs:42:21
Expected type: (xs, String)
  Actual type: (String, String)
In the first argument of ‘fst’, namely ‘x’
In the expression: fst x

2 个答案:

答案 0 :(得分:3)

快速修复

替换:

(snd x,fst x) ++ (tupleXTurn xs)

使用:

(snd x,fst x) : (tupleXTurn xs)

运算符(++)用于连接两个列表。要将元素添加到列表中,您应该使用(:)

您还应该注意到您的函数无法与函数定义中的[]匹配。所以你应该:

tupleXTurn :: [(String, String)]->[(String, String)]
tupleXTurn [] = []
tupleXTurn (x:xs) = (snd x,fst x) : (tupleXTurn xs)

Live demo

改善功能

您还可以将功能类型放宽到:

[(a, b)] -> [(b, a)]

最后,您可以根据mapswap(来自Data.Tuple)来定义您的功能:

tupleXTurn :: [(a, b)]->[(b, a)]
tupleXTurn = map swap

Live demo

答案 1 :(得分:2)

错误是因为您尝试使用++连接元组和列表。当您想要将两个列表连接在一起时使用此选项,但是您希望将一个元素添加到列表的前面,因此您应该使用:运算符:

tupleXTurn (x:xs) = (snd x, fst x) : tupleXTurn xs

更惯用的方法是定义一个函数来交换单个元组然后使用map

swap :: (a, b) -> (b, a)
swap (a, b) = (b, a)

tupleXTurn :: [(String, String)] -> [(String, String)]
tupleXTurn xs = map swap xs

这也避免了必须处理空列表的问题,因为如果给出一个空列表作为其参数,你的函数也会出错,因为它与模式(x:xs)不匹配,但是map已经为您解决了这个问题。

仅供参考:swap已在Data.Tuple中定义,因此您甚至无需自行定义。