我正在编写一个简单的程序来查找给定列表是否为矩阵:
is_matrix :: [[a]] -> Bool
is_matrix [[]] = False
is_matrix (x:xs)
| x == [] = is_matrix xs
| x == [a] = True
| length x == length (head xs) = is_matrix xs
| otherwise = False
但是当我编译is_matrix.hs
文件时,它会产生以下错误:
Prelude> :load is_matrix.hs
[1 of 1] Compiling Main ( is_matrix.hs, interpreted )
is_matrix.hs:5:11: Not in scope: `a'
Failed, modules loaded: none.
Prelude>
我不知道为什么会这样?
答案 0 :(得分:3)
a
不是变量,它是您定义中的类型,因此您无法编写x == [a]
。
我想您要检查x
是否是单个元素列表。如果是这样,你可以写出这样的条件
is_matrix :: [[a]] -> Bool
is_matrix [[]] = False
is_matrix ([]:xs) = is_matrix xs
is_matrix ([x]:xs) = True
is_matrix (x:xs)
| length x == length (head xs) = is_matrix xs
| otherwise = False
请注意,当您对条件使用|
时,将使用范围中的变量,不绑定新变量。相反,当使用函数模式匹配时,左侧的变量与它们的匹配绑定。
顺便说一句,Haskell通常使用camelCase而不是snake_case。
答案 1 :(得分:2)
我不确定,您要尝试使用表达式x == [a]
进行检查,因为[a]
是" a
'的列表; S" 。让我们尝试使用Wiki中的矩阵定义实现该功能:
矩阵是数字或其他数学的矩形数组 对象,对其进行加法和乘法等操作 定义
因此,我们需要检查的是矩阵中的所有行都具有相同的大小。另请注意,有一种情况,即所谓的空矩阵:
在某些情况下,例如计算机代数程序,它是有用的 考虑一个没有行或没有列的矩阵,称为空矩阵。
is_matrix :: [[a]] -> Bool
-- Note, I removed the is_matrix [[]] = False condition
is_matrix (x:xs)
| null xs = True -- There are no more rows in sub-matrix - the answer is True
| length x == length (head xs) = is_matrix xs -- The same as in your version
| otherwise = False -- The same as in your version
此函数产生以下输出:
*Main> is_matrix [[]]
True
*Main> is_matrix [[1, 2, 3], [4, 5, 6]]
True
*Main> is_matrix [[1, 2, 3], [7], [4, 5, 6]]
此功能也可以使用map
函数(the question about implementation of allTheSame
function)以更自然的方式实现:
*Main> let allTheSame xs = all (== head xs) (tail xs)
*Main> let isMatrix = allTheSame . map length
*Main> isMatrix [[]]
True
*Main> isMatrix [[1, 2, 3], [4, 5, 6]]
True
*Main> isMatrix [[1, 2, 3], [7], [4, 5, 6]]
False