从列表中的偶数位置取元素 [英] Take elements on even positions from the list
问题描述
问题:使用 fold ,从位于偶数位置的列表元素中取出:
Problem: using fold, take from the list elements which are on the even positions:
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..]
I decided at first to get a list of alternating 0
-es and 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]
然后 zip 将其与原始列表一起,得到成对的列表:[(x1, 0), (x2,1), (x3,0) .. (xn, ?)]
:
Then zip it with the original list, getting a list of pairs: [(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
具有过滤功能的对列表和一个空列表作为初始化值.
After that, foldr
the list of pairs with a filtering function and an empty list as initialization value.
所以我认为这会起作用:
So I thought that this would work:
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)
但是它给出了一个我不理解的错误:
But it gives an error, that I don't understand:
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)
我认为我的想法是正确的,我只是在语法上做了些错误.
I think my idea is correct, I just did something wrong with the syntax.
推荐答案
(.)
是函数组成,而zip g xs
是不是函数的列表.您可以直接将结果列表用作foldr
的参数.请注意,参数g
和xs
的顺序错误:
(.)
is function composition but zip g xs
is a list not a function. You can just apply the resulting list as the argument to foldr
directly. Note you have the arguments g
and xs
in the wrong order:
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 xs g)
这篇关于从列表中的偶数位置取元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!