【问题标题】:Inverting List Elements in Haskell在 Haskell 中反转列表元素
【发布时间】:2017-03-07 02:06:01
【问题描述】:

我正在尝试反转 xs 中的两个元素列表。例如,invert [[1,2], [5,6,7], [10,20]] 将返回 [[2,1], [5,6,7], [20,10]]。它不会反转 [5,6,7],因为它是一个 3 元素列表。

所以到目前为止我已经写了这个:

invert :: [[a]] -> [[a]]
invert [[]] = [[]]

这只是类型声明和空列表案例。我是 Haskell 的新手,所以关于如何实现这个问题的任何建议都会有所帮助。

【问题讨论】:

    标签: list haskell


    【解决方案1】:

    这是一种方法:

    首先我们定义一个函数来反转一个列表(如果它有两个元素;否则我们返回列表不变):

    invertOne :: [a] -> [a]
    invertOne [x, y] = [y, x]
    invertOne xs = xs
    

    接下来我们将这个函数应用于输入列表的所有元素:

    invert :: [[a]] -> [[a]]
    invert xs = map invertOne xs
    

    (因为这正是map 所做的:它将一个函数应用于列表的所有元素,并将结果收集到另一个列表中。)

    【讨论】:

      【解决方案2】:

      您的惰性函数只是单独对每个元素进行操作,因此您可以将其表示为map

      invert xs = map go xs
        where go = ...
      

      这里go 只是根据您的规则反转单个列表,即:

      go [1,2] = [2,1]
      go [4,5,6] = [4,5,6]
      go []    = []
      

      go 的定义非常简单:

      go [a,b] = [b,a]
      go xs    = xs     -- go of anything else is just itself
      

      【讨论】:

        【解决方案3】:

        我会这样做:

        solution ([a,b]:xs) = [b,a] : solution xs
        solution (x:xs)     = x : solution xs
        solution []         = []
        

        这会显式处理 2 元素列表,而无需理会其他所有内容。

        是的,您可以使用 map 和一个辅助函数来做到这一点,但对于初学者来说,了解这一切背后的递归可能很有价值。

        请注意,您的“空列表案例”不是为空的。 length [[]] 是 1。

        【讨论】:

          【解决方案4】:

          检查以下解决方案:

          invert :: [[a]] -> [[a]]
          invert = fmap conditionallyInvert
            where
              conditionallyInvert xs
                | lengthOfTwo xs = reverse xs
                | otherwise      = xs
              lengthOfTwo (_:_:_) = True
              lengthOfTwo      _  = False
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-09-21
            • 1970-01-01
            • 2015-01-06
            • 1970-01-01
            • 1970-01-01
            • 2015-02-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多