List 反转Haskell列表中的每个偶数元素

List 反转Haskell列表中的每个偶数元素,list,haskell,element,List,Haskell,Element,在Haskell中给出了一个列表,但您应该反转每个偶数元素。例如列表 f ["rehtruF", "dooG", kcuL"] 应该改成 ["Further", "Good" "Luck"] 我们尝试了以下功能: f [] = [] f [x] = [] f (xs:ys:xss) = (reverse xs):(f xss) 但不幸的是,它只反转了第一个元素并将其打印出来。您知道

在Haskell中给出了一个列表,但您应该反转每个偶数元素。例如列表

f ["rehtruF", "dooG", kcuL"]
应该改成

["Further", "Good" "Luck"]
我们尝试了以下功能:

f [] = []
f [x] = []
f (xs:ys:xss) = (reverse xs):(f xss)

但不幸的是,它只反转了第一个元素并将其打印出来。您知道我们如何更改代码,以便保留每个偶数元素,并且输出如上所示吗?

问题是您完全删除了ys元素。你真正想要的是保持原样,即在结果列表中保持原样

f (xs:ys:xss) = reverse xs : ys : f xss

请注意,如果您打开了-Wall选项,GHC会警告您未使用的ys绑定,这对于初学者来说通常是个好主意。您可以通过使用ghc-Wall YOURFILE.hs执行编译器/解释器,或者在GHCi会话中键入:set-Wall来实现这一点。

问题是您完全删除了ys元素。你真正想要的是保持原样,即在结果列表中保持原样

f (xs:ys:xss) = reverse xs : ys : f xss

请注意,如果您打开了-Wall选项,GHC会警告您未使用的ys绑定,这对于初学者来说通常是个好主意。您可以通过使用ghc-Wall YOURFILE.hs执行编译器/解释器,或者在GHCi会话中键入:set-Wall来执行此操作。

要反转列表中的偶数元素,首先要查找偶数元素,其中一种方法是首先为列表中的每个元素编制索引,如下所示:

zip [0..] xs
然后,我们反转元素的偶数索引:

if index `mod` 2 == 0 then reverse x else x
把它们都当作

f xs = map reverseEven (zip [0..] xs)
    where reverseEven (index, x) = if index `mod` 2 == 0 
                                   then reverse x else x

要反转列表中的偶数元素,首先要找到偶数元素,其中一种方法是首先对列表中的每个元素进行索引,如下所示:

zip [0..] xs
然后,我们反转元素的偶数索引:

if index `mod` 2 == 0 then reverse x else x
把它们都当作

f xs = map reverseEven (zip [0..] xs)
    where reverseEven (index, x) = if index `mod` 2 == 0 
                                   then reverse x else x

TL;DR-这是基于Thomas M.DuBuisson在其评论中提到的解决方案。哎呀

您甚至不需要显式地迭代输入。假设你有一个函数列表fs=[f0,f1,f2,…]和一个值列表xs=[x0,x1,x2,…],你想得到[f0-x0,f1-x1,f2-x2,…]。您可以使用zipWith$执行此操作:

对于您的问题,您的fs将是反向和id的交替序列,您可以使用cycle[reverse,id]==[reverse,id,reverse,id,…]生成此序列

把这些放在一起

f :: [String] -> [String]
f strings = zipWith ($) (cycle [reverse, id]) strings
        -- == [reverse strings0, id strings0, reverse strings2, id strings3, ...]
或者干脆

f :: [String] -> [String]
f = zipWith ($) (cycle [reverse, id])

TL;DR-这是基于Thomas M.DuBuisson在其评论中提到的解决方案。哎呀

您甚至不需要显式地迭代输入。假设你有一个函数列表fs=[f0,f1,f2,…]和一个值列表xs=[x0,x1,x2,…],你想得到[f0-x0,f1-x1,f2-x2,…]。您可以使用zipWith$执行此操作:

对于您的问题,您的fs将是反向和id的交替序列,您可以使用cycle[reverse,id]==[reverse,id,reverse,id,…]生成此序列

把这些放在一起

f :: [String] -> [String]
f strings = zipWith ($) (cycle [reverse, id]) strings
        -- == [reverse strings0, id strings0, reverse strings2, id strings3, ...]
或者干脆

f :: [String] -> [String]
f = zipWith ($) (cycle [reverse, id])

一个人不应该计算任何不需要计算的东西。无拉链,无自行车,无需改装

第一个元素被认为位于索引0处,即处于偶数位置,如问题中所述

> foo ["Further","Good","Luck"]
["rehtruF","Good","kcuL"]

> foo $ foo ["Further","Good","Luck"]
["Further","Good","Luck"]
对于普通递归,上述基于foldr的定义所做的是:

foo = f   where 
      f (x:xs)  =  reverse x : g xs
      g (x:xs)  =  x : f xs 
,加上明显的[]处理案例


对于foldr,[]由foldr自身检查;对于相互递归,它必须由两个协作函数中的每一个来完成。

一个人不应该计算任何不需要计算的东西。无拉链,无自行车,无需改装

第一个元素被认为位于索引0处,即处于偶数位置,如问题中所述

> foo ["Further","Good","Luck"]
["rehtruF","Good","kcuL"]

> foo $ foo ["Further","Good","Luck"]
["Further","Good","Luck"]
对于普通递归,上述基于foldr的定义所做的是:

foo = f   where 
      f (x:xs)  =  reverse x : g xs
      g (x:xs)  =  x : f xs 
,加上明显的[]处理案例


对于foldr,[]由foldr自身检查;对于相互递归,它必须由两个协作函数中的每一个来完成。

如果您添加了一个额外的变量,那么您可以跟踪偶数元素或奇数元素。例如,这里我们使用1表示奇数,0表示偶数:

f = f' 1
  where
    f' _ []     = []
    f' 1 (x:xs) = reverse x: f' 0 xs
    f' 0 (x:xs) = x: f' 1 xs

如果您添加了一个额外的变量,则可以跟踪偶数元素或奇数元素。例如,这里我们使用1表示奇数,0表示偶数:

f = f' 1
  where
    f' _ []     = []
    f' 1 (x:xs) = reverse x: f' 0 xs
    f' 0 (x:xs) = x: f' 1 xs

提示:试试地图reverse@assembly.jc这在这里一点帮助都没有。如果你用手减少,你首先会得到反向重新计算:f[kcuL],其中好的缺失是一个明确的线索,表明你在结果中遗漏了一些东西。另请参阅。为了满足您的需要,而不是您想要使用的函数*2和id和id。提示:请尝试映射reverse@assembly.jc这在这里一点帮助都没有。如果你用手减少,你首先会得到反向重新计算:f[kcuL],其中好的缺失是一个明确的线索,表明你在结果中遗漏了一些东西。另请参阅。为了满足您的需要,而不是函数*2和id,您希望使用id和reverse。在singleton情况下,最后一个元素也会被删除。在singleton情况下,最后一个元素也会被删除。循环和压缩也会被删除,就像使用mod一样:这是我的
到目前为止最喜欢的一款。骑自行车和拉拉链也是,就像mod一样这是到目前为止我最喜欢的一个。