我不知道发生了什么事。
我有一份清单
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 []
我该怎么办?
答案 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.Applicative
和Data.Traversable
模块中。它的定义与Stefan Holdermans中的模式类型和包装 - 展开的东西相同。