Haskell 处理元组和绑定

Haskell 处理元组和绑定,haskell,tuples,Haskell,Tuples,我正在编写一个函数,它对元组列表中的元素求和,如下所示: sumAll [(2,4,11), (3,1,-5), (10,-3,6)] = (15,2,12) 我确实有这个: sumAll :: (Num a, Num b, Num c) => [(a,b,c)] -> (a,b,c) sumAll l = (foldr (+) 0 as, foldr (+) 0 bs, foldr (+) 0 cs) where trd (a,b,c) = c

我正在编写一个函数,它对元组列表中的元素求和,如下所示:

sumAll [(2,4,11), (3,1,-5), (10,-3,6)] = (15,2,12)
我确实有这个:

sumAll :: (Num a, Num b, Num c) => [(a,b,c)] -> (a,b,c)
sumAll l = (foldr (+) 0 as, foldr (+) 0 bs, foldr (+) 0 cs) 
               where trd (a,b,c) = c
                     as = (map (fst) l) 
                     bs = (map (snd) l)
                     cs = (map (trd) l)
然而,编译器抱怨:

Couldn't match type `(a, b, c)' with `(b1, b0)'
    Expected type: [(b1, b0)]
      Actual type: [(a, b, c)]
    Relevant bindings include
      as :: [b1] (bound at ficha3.hs:22:22)
      cs :: [c] (bound at ficha3.hs:24:22)
      l :: [(a, b, c)] (bound at ficha3.hs:20:12)
      sumAll :: [(a, b, c)] -> (a, b, c) (bound at ficha3.hs:20:1)
    In the second argument of `map', namely `l'
    In the expression: (map (fst) l)
表达式(map(snd)l)也是如此

如果我从函数定义中删除“c”参数,它就会工作。 像这样:

sumAll :: (Num a, Num b) => [(a,b)] -> (a,b)
sumAll l = (foldr (+) 0 as, foldr (+) 0 bs) 
               where as = (map (fst) l) 
                     bs = (map (snd) l)
如果可能的话,我的问题是:

  • 为什么“c”会“扭曲”输出元组
  • 我怎样才能解决这个问题

  • 考虑如何定义您的
    fst
    snd
    trd
    。如果您使用的是
    Prelude
    中的
    fst
    ,那么它有一种类型的
    fst:(a,b)->a
    ,它不适用于3元组。

    考虑一下您的
    fst
    snd
    trd
    是如何定义的。如果您使用的是
    Prelude
    中的
    fst
    ,那么它有一种类型的
    fst::(a,b)->a
    ,它不适用于三元组。

    重新定义了函数fst和snd。非常感谢。重新定义了功能fst和snd。非常感谢。样式注释:
    (map(fst)l)
    更常用于编写
    map fst l
    ——不需要括号。如果要对所有元素应用操作,统一元组有点麻烦。如果使用列表而不是元组,则可以将
    sumAll
    简单地写成
    foldr(zipWith(+))[0,0..]::Num a=>[[a]]->[a]
    。但是,最短的输入列表将决定输出的长度。样式注释:
    (map(fst)l)
    更常用于编写
    map fst l
    ——不需要括号。如果要对所有元素应用操作,统一元组有点烦人。如果使用列表而不是元组,则可以将
    sumAll
    简单地写成
    foldr(zipWith(+))[0,0..]::Num a=>[[a]]->[a]
    。然而,最短的输入列表将决定输出的长度。