在Haskell

时间:2015-12-22 19:40:40

标签: haskell

我有这种类型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任何帮助。

5 个答案:

答案 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表示,而当前元素由[[],[],[]]表示。