Haskell - 如何遍历列表和反转元素

时间:2015-09-12 00:00:52

标签: haskell

我无法在Haskell中找到有关简单操作的文档。

我有一个列表列表(:: [[a]]),我需要撤消所有元素列表x length x >= 2

到目前为止,我还没有找到任何东西:

  • 如何遍历列表

  • 如何找到元素的长度。我可以使用length函数,但我不知道如何使用它。

我确实找到了列表的reverse函数,但我找不到它。

如果对这些个别实施有任何帮助,我们将不胜感激。我可以把它们拼凑起来。

5 个答案:

答案 0 :(得分:7)

  

我需要反转所有元素列表x length x >= 2

你可以完全忽略length x >= 2部分,因为如果列表的长度为0或1,则反转它没有效果:没有办法判断你是否反转它,所以为了统一,你也可以反转所有列表。

鉴于此,这非常简单:你只需要在列表列表上map reverse,依次颠倒每个列表:

reverseEach :: [[a]] -> [[a]]
reverseEach = map reverse

> reverseEach [[1,2,3],[4],[5,6,7,8]]
[[3,2,1],[4],[8,7,6,5]]

正如其他答案所暗示的那样,你可以稍微概括一下:

reverseEach :: Functor f => f [a] -> f [a]
reverseEach = fmap reverse

> reverseEach [[1,2,3],[4],[5,6,7,8]]
[[3,2,1],[4],[8,7,6,5]]

答案 1 :(得分:2)

  

如何遍历列表。

有几个序列函数,从更基本的fmap,将单个函数映射到列表,到foldr,它围绕二进制操作折叠列表结构(用于汇总列表或类似的操作)sequence / traverse操作,具有一元或应用效果。

  

我如何找到元素的长度。我可以使用长度函数,但我不知道如何使用它。

length个功能;你像任何其他功能一样使用它。 length xs,其中xs是一个列表。如果您仍然不确定如何做到这一点,我建议您使用Haskell教程慢慢开始。

  

我有这个要反转清单,但我想我现在已经有了。

有一个reverse功能。如果您不想使用内置的(或者如果您想自己为了教育目的而这样做),您可以使用累加器构建一个有效的反向函数。

reverse' :: [a] -> [a]
reverse' xs = doReverse xs []
    where doReverse [] ys = ys
          doReverse (x:xs) ys = doReverse xs (x:ys)

答案 2 :(得分:0)

<强>解决方案:

length

我们将函数conditionallyReverse :: [[a]] -> [[a]] ConditionallyReverse listOfLists= fmap f listOfLists where f list | length list >= 2 = reverse x | otherwise = x 应用于f的每个元素,方法是将listOfLists作为f的第一个参数,将fmap作为第二个参数提供。函数listOfLists根据条件f转换list。如果条件成立,则列表反转,否则返回原始列表。

答案 3 :(得分:0)

荒谬的过度概括:

每个Traversable实例都支持实施reverse的可怕黑客攻击。可能有更清洁或更有效的方法来做到这一点;我不确定。

module Rev where
import Data.Traversable
import Data.Foldable
import Control.Monad.Trans.State.Strict
import Prelude hiding (foldl)

fill :: Traversable t => t b -> [a] -> t a
fill = evalState . traverse go
  where
    go _ = do
      xs <- get
      put (drop 1 xs)
      return (head xs)

reverseT :: Traversable t => t a -> t a
reverseT xs = fill xs $ foldl (flip (:)) [] xs

reverseAll :: (Functor f, Traversable t) => f (t a) -> f (t a)
reverseAll = fmap reverseT

答案 4 :(得分:0)

就折叠而言:

reverse  =  foldl (\ acc x -> x : acc) []
length  =  foldl' (\ n _ -> n + 1) 0
map f  =  foldr (\ x xs -> f x : xs)

mapReverse  =  map (\ xs -> if length xs >= 2 then reverse xs else xs)

但是length是昂贵的O(n)和reverse [x] = [x]。我会用

map reverse [[1,2,3],[4],[]]  ==  [[3,2,1],[4],[]]

其中(map reverse) :: [[a]] -> [[a]]map reverse不足以证明自己的名字绑定。