从列表中的偶数位置取元素 [英] Take elements on even positions from the list

查看:80
本文介绍了从列表中的偶数位置取元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:使用 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的参数.请注意,参数gxs的顺序错误:

(.) 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆