不在范围错误

时间:2015-08-28 08:05:20

标签: haskell

我正在编写一个简单的程序来查找给定列表是否为矩阵:

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>

我不知道为什么会这样?

2 个答案:

答案 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