Haskell列表有问题

时间:2014-12-09 18:34:01

标签: list haskell head

我不知道发生了什么事。 我有一份清单 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 []

我该怎么办?

2 个答案:

答案 0 :(得分:4)

您反复捕捉函数输入中每个列表的正面和反面。最终,其中一个列表只剩下空列表作为尾部,然后尝试占用该空列表的头部将失败。

  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导出。

答案 1 :(得分:0)

您可以在一行中重新定义transpose功能:

transpose = getZipList . traverse ZipList

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