我有这种类型Mat a = [[a]]
来表示haskell中的矩阵。
我必须编写一个旋转矩阵的函数,例如[[1,2,3],[0,4,5]
,[0,0,6]]
将成为[[3,5,6],[2,4,0],[1,0,0]]
所以我做了这个:
rotateLeft :: Mat a->Mat a
rotateLeft [[]] = []
rotateLeft (h:t) = (map last (h:t)):(rotateLeft (map init (h:t)))
但输出是
[[3,5,6],[2,4,0],[1,0,0],[*** Exception: Prelude.last: empty list
我不知道在基本情况下要放什么来避免这种异常。 Apreciate任何帮助。
答案 0 :(得分:6)
我是一个匆忙的老人。我这样做(导入Data.List
)
rotl :: [[x]] -> [[x]]
rotl = transpose . map reverse
答案 1 :(得分:2)
您的列表不是空的,而是空列表的列表,您可以根据第一个子列表进行模式匹配(假设Mat确保数据结构的一致性)
rl [] = []
rl ([]:_) = []
rl m = map last m : (rl (map init m))
rl mat
[[3,5,6],[2,4,0],[1,0,0]]
你错过了第二种情况。
答案 2 :(得分:2)
我认为最简单的解决方案是:
import Data.List
rotateLeft :: [[a]] -> [[a]]
rotateLeft = reverse . transpose
rotateRight :: [[a]] -> [[a]]
rotateRight = transpose . reverse
Data.List是一个标准模块。
将行切片成列,这几乎就像旋转一样,但是列的顺序错误,所以我们只需将它们反转。
答案 3 :(得分:0)
tintColor
第一种模式适用于列表列表的头部长于其他元素的情况。
你得到第二个模式错误:如果我们有一个合适的矩阵(即元素长度相同),那么基本情况就是一个空列表列表。但是,您编写了[[]],仅当初始列表包含单个列表时才会出现。
答案 4 :(得分:0)
问题是您的模式不匹配。逐步完成代码的工作,我们从:
开始tintColor
因此,基本问题是您匹配的基本情况不是UIBarButtonItems
,而是UIAppearance
,因此模式不匹配。
您现在有三个或多或少的选项:您可以(a)尝试在看到第一个空列表时终止;这是在Haskell中用rotateLeft [] = []
rotateLeft ([]:_) = []
rotateLeft (h:t) = (map last (h:t)):(rotateLeft (map init (h:t)))
编写的,使用Prelude> let x = [[1,2,3],[0,4,5],[0,0,6]]
Prelude> :m +Data.List
Prelude Data.List> map last x
[3,5,6]
Prelude Data.List> let y = map init x
Prelude Data.List> y
[[1,2],[0,4],[0,0]]
Prelude Data.List> map last y
[2,4,0]
Prelude Data.List> let z = map init y
Prelude Data.List> z
[[1],[0],[0]]
Prelude Data.List> map last z
[1,0,0]
Prelude Data.List> map init z
[[],[],[]]
函数和[[],[],[]]
函数,两者都在Prelude中定义;或者(b)您可以硬编码,这仅适用于3x3矩阵,只匹配[[]]
,或者(c)您可以尝试在所有列表为空(any null
)时终止,在这种情况下您可以跳过不存在的元素或将所有内容包装在any
数据类型中,以便缺少的元素由null
表示,而当前元素由[[],[],[]]
表示。