我有一个类型为(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
3条答案
按热度按时间0yycz8jy1#
代码中有几个问题,都与参数顺序有关:
foldl和所有其他folds一样,将参数列表作为它的 last(第3个)参数,并将起始累加器(您的
[]
)作为它的前一个参数--所以您需要在定义中切换list
和[]
。类似地,fold函数本身的类型为
b -> a -> b
--也就是说,它将旧的累加器作为第一个元素,将正在折叠的列表中的元素作为第二个元素,因此,在您的示例中,第一个参数是一个双精度型列表,第二个参数是一对双精度型(不是一个列表)-你的实现和变量名清楚地暗示你认为它是相反的,但是编译器不能接受这一点。(Note对于右折叠,参数顺序是相反的。这可能会让人困惑--我总是在脑海中把当前累加器放在列表的一端来记住它:左折叠的左端和右折叠的右端,然后注意fold函数是按照从左到右的顺序使用参数的,如果这对你没有帮助,不要担心,我可能已经解释得很糟糕了,这不是必需的,但它对我有帮助!)
因此,当你的函数固定在上述两种方式将看起来像这样:
最后要注意的是,用
map
函数来表达要简单得多,也更易读--它(正如您在这里所做的)将一个函数应用于列表的每个元素。或者通过“η还原”,仅仅:
l7wslrjt2#
我想你要找的是
map
(https://hackage.haskell.org/package/base-4.17.0.0/docs/Prelude.html#v:map)它接受一个列表并对每个元素应用一个给定的函数
或者更明确一点
把这个加载到GHCI中
cwxwcias3#
最简单的方法是使用
map
:你也可以让它在
foldr
上工作:或者用
foldl
,但是这将在二次时间内起作用,并且仅当在所有元素上枚举时才产生结果: