使用地图haskell列出的元组列表

ove*_*ter 6 haskell

我想转换元组列表:[(2,2,2),(3,3,3),(4,4,4),(5,5,5)]到列表:[2,2, 2,3,3,3,4,4,4,5,5,5]

我试试这个

map (\(a,b,c,d)->a:b:c:d) listOfTuples
Run Code Online (Sandbox Code Playgroud)

但得到一个错误.

Prelude> map (\(a,b,c)->a:b:c) [(1,2,3), (5,6,7)]

<interactive>:1:37:
    No instance for (Num [t])
      arising from the literal `7' at <interactive>:1:37
    Possible fix: add an instance declaration for (Num [t])
    In the expression: 7
    In the expression: (5, 6, 7)
    In the second argument of `map', namely `[(1, 2, 3), (5, 6, 7)]'

Prelude>
Run Code Online (Sandbox Code Playgroud)

我怎么能用lambda做到这一点?为什么我的东西不起作用?

ehi*_*ird 13

a:b:c:d因为它是无效的a : (b : (c : d)).(:)在右侧列出一个列表,在左侧列出一个元素,但是d是另一个元素,而不是(必然)列表.你可能意味着a:b:c:d:[],这是一样的[a,b,c,d].

如果进行了更改,代码将运行并生成[[2,2,2], [3,3,3], [4,4,4], [5,5,5]],因为map将函数应用于列表的每个元素,并将其结果用作新元素; 也就是说,不能改变列表的结构,只能每个元素独立.如果你想要它变平,你需要使用concat(具有类型[[a]] -> [a],并展平列表列表):

concat (map (\(a,b,c,d) -> [a,b,c,d]) listOfTuples)
Run Code Online (Sandbox Code Playgroud)

然而,存在的一个现成的组合物concatmap,这是更惯用的使用方法:

concatMap (\(a,b,c,d) -> [a,b,c,d]) listOfTuples
Run Code Online (Sandbox Code Playgroud)

  • 或者:`foldr(\(a,b,c)l - > a:b:c:l)[] [(1,2,3),(4,5,6)]` (11认同)
  • @overwriter:不,你不能只用`map`来做,因为输入列表的每个元素都映射到输出列表中的一个元素. (5认同)
  • 由于列表monad的实现方式,这将打开:`[(a,b,c),(d,e,f)] >> = \(x,y,z) - > [x,y, Z]` (3认同)