【发布时间】:2019-12-22 07:47:07
【问题描述】:
问题:使用折叠,从列表中取出偶数位置的元素:
GHCi> evenOnly [1..10]
[2,4,6,8,10]
GHCi> evenOnly ['a'..'z']
"bdfhjlnprtvxz"
evenOnly :: [a] -> [a]
evenOnly = undefined
我首先决定获取0-es 和1-s 的交替列表:[0,1,0,1..]
Prelude> let g = iterate (\x -> (x + 1) `mod` 2) 0
Prelude> take 10 $ g
[0,1,0,1,0,1,0,1,0,1]
然后将其与原始列表压缩,得到一对列表:[(x1, 0), (x2,1), (x3,0) .. (xn, ?)]:
Prelude> zip g [1,2,3,4,5]
[(0,1),(1,2),(0,3),(1,4),(0,5)]
之后,foldr 具有过滤功能的对列表和一个空列表作为初始化值。
所以我认为这会起作用:
evenOnly :: [a] -> [a]
evenOnly xs = let g = iterate (\x -> (x + 1) `mod` 2) 0
in
foldr (\ (x, n) s -> if n == 1 then x : s else s) [] . (zip g xs)
但它给出了一个我不明白的错误:
foldr.hs:44:59: error:
• Couldn't match expected type ‘a0 -> t0 (a1, Integer)’
with actual type ‘[(Integer, a)]’
• Possible cause: ‘zip’ is applied to too many arguments
In the second argument of ‘(.)’, namely ‘(zip g xs)’
In the expression:
foldr (\ (x, n) s -> if n == 1 then x : s else s) [] . (zip g xs)
In the expression:
let g = iterate (\ x -> (x + 1) `mod` 2) 0
in
foldr (\ (x, n) s -> if n == 1 then x : s else s) [] . (zip g xs)
• Relevant bindings include
xs :: [a] (bound at foldr.hs:42:10)
evenOnly :: [a] -> [a] (bound at foldr.hs:42:1)
我认为我的想法是正确的,我只是在语法上做错了。
【问题讨论】:
标签: list haskell syntax fold type-mismatch