【问题标题】:Something wrong with a Haskell ListHaskell 列表有问题
【发布时间】:2014-12-09 18:34:00
【问题描述】:

我不知道这发生了什么。 我有一个清单 L = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

我需要一个函数来给我这个: L = [[1, 4, 7],[2, 5, 8],[3, 6, 9]]

直到现在我有这个:

rotar2 [ ] = [ ]
rotar2 l = [map head l] ++ rotar2(map tail l)

它有效但根本没有.. 它向我发送了这个错误:

[[1,4,7],[2,5,8],[3,6,9],[ Program error: pattern match failure: head []

我该怎么办?

【问题讨论】:

  • 您尝试定义的函数很容易获得 - 它被称为transpose
  • 当你rotar2 [[]]时会发生什么?
  • @n.m.它给我发送了同样的错误
  • 我知道它给你发送了什么,你知道为什么吗?
  • 你在map headl,但没有理由仅仅因为l 本身是非空的就假设l 包含非空列表。如果您继续map tail 在列表列表上,最终,其中一个元素将是一个空列表。

标签: list haskell head


【解决方案1】:

您在函数输入中反复获取每个列表的首尾。最终,这些列表之一将只留下空列表作为尾部,然后尝试获取该空列表的头部将失败。

  rotar2 [[1,2,3],[4,5,6],[7,8,9]]
    = [[1,4,7]] ++ rotar2 [[2,3], [5,6], [8,9]]
    = [[1,4,7]] ++ [[2,5,8]] ++ rotar2 [[3], [6], [9]]
    = [[1,4,7]] ++ [[2,5,8]] ++ [[3,6,9]] ++ rotar2 [[],[],[]]
    = [[1,4,7]] ++ [[2,5,8]] ++ [[3,6,9]] ++ [head [],head[],head []] ++ ...
    = [[1,4,7],[2,5,8],[3,6,9],[⊥,⊥,⊥],...]

转置

您尝试定义的函数rotar2 通常称为transpose,并且可以相当直接地实现为

transpose :: [[a]] -> [[a]]
transpose []         = repeat []
transpose (xs : xss) = zipWith (:) xs (transpose xss)

这个想法是,一个非空列表,比如[[1,2,3],[4,5,6],[7,8,9]],可以通过首先转置它的尾部[[4,5,6],[7,8,9]],产生[[4,7],[5,8],[6,9]],然后将头部列表[1,2,3]的元素添加到转置尾的元素:

[ 1 : [4,7] , 2 : [5,8] , 3 : [6,9] ]

因此:

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

在标准库中,该函数由模块Data.List导出。

【讨论】:

    【解决方案2】:

    您可以在一行中重新定义transpose 函数:

    transpose = getZipList . traverse ZipList
    

    所有的定义和实例都在Control.ApplicativeData.Traversable 模块中。它与 Stefan Holdermans 的答案模类型类和包装 - 展开的东西中的定义相同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-02
      • 2019-06-03
      • 2013-05-02
      • 1970-01-01
      • 2010-12-02
      相关资源
      最近更新 更多