haskell 如何从元组列表中获取值列表?

mum43rcc  于 2022-12-23  发布在  其他
关注(0)|答案(3)|浏览(178)

我有一个类型为(x,y)的值表,我想得到一个x表,但是出错了,下面是代码:

x_list:: [(Double, Double)] -> [Double]
x_list list = Prelude.foldl(\t xl -> (fst t):xl) list []

我得到这个错误:

• Couldn't match expected type: (Double, b0)
                  with actual type: [Double]
    • In the first argument of ‘fst’, namely ‘t’
      In the first argument of ‘(:)’, namely ‘(fst t)’
      In the expression: (fst t) : xl
0yycz8jy

0yycz8jy1#

代码中有几个问题,都与参数顺序有关:
foldl和所有其他folds一样,将参数列表作为它的 last(第3个)参数,并将起始累加器(您的[])作为它的前一个参数--所以您需要在定义中切换list[]
类似地,fold函数本身的类型为b -> a -> b--也就是说,它将旧的累加器作为第一个元素,将正在折叠的列表中的元素作为第二个元素,因此,在您的示例中,第一个参数是一个双精度型列表,第二个参数是一对双精度型(不是一个列表)-你的实现和变量名清楚地暗示你认为它是相反的,但是编译器不能接受这一点。
(Note对于右折叠,参数顺序是相反的。这可能会让人困惑--我总是在脑海中把当前累加器放在列表的一端来记住它:左折叠的左端和右折叠的右端,然后注意fold函数是按照从左到右的顺序使用参数的,如果这对你没有帮助,不要担心,我可能已经解释得很糟糕了,这不是必需的,但它对我有帮助!)
因此,当你的函数固定在上述两种方式将看起来像这样:

x_list:: [(Double, Double)] -> [Double]
x_list list = Prelude.foldl(\xl t -> (fst t):xl) [] list

最后要注意的是,用map函数来表达要简单得多,也更易读--它(正如您在这里所做的)将一个函数应用于列表的每个元素。

x_list list = map fst list

或者通过“η还原”,仅仅:

x_list = map fst
l7wslrjt

l7wslrjt2#

我想你要找的是map(https://hackage.haskell.org/package/base-4.17.0.0/docs/Prelude.html#v:map)
它接受一个列表并对每个元素应用一个给定的函数

xList :: [(Double,Double)] -> [Double]
xList = map fst

或者更明确一点

xList' :: [(Double,Double)] -> [Double]
xList' list = map (\(x,y) -> x) list

把这个加载到GHCI中

ghci> xList' [(1,2),(3,4)]
[1.0,3.0]
cwxwcias

cwxwcias3#

最简单的方法是使用map

x_list :: [(a, b)] -> [a]
x_list = map fst

你也可以让它在foldr上工作:

x_list :: [(a, b)] -> [a]
x_list list = foldr (\(t, _) xl -> t:xl) [] list

或者用foldl,但是这将在二次时间内起作用,并且仅当在所有元素上枚举时才产生结果:

x_list :: [(a, b)] -> [a]
x_list list = foldl (\xl (t, _) -> xl ++ [t]) [] list

相关问题