2015-08-28 51 views
2

我寫一個簡單的程序來找到一個給定的名單是否是一個矩陣與否:不在範圍內誤差

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> 

我不知道爲什麼會發生這種情況?

+1

那麼,'a'是什麼?我猜你實際上是指'長度x == 1',或者'isSingleton x',其中'isSingleton x = 1 x == x' – Zeta

回答

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。

+0

當我用'is_matrix [[2,3],[4, 5],[6,7]]或'[2,3,4,5,6,7]'它給這個錯誤'***例外:Prelude.head:空列表' –

+0

我真的沒有看邏輯,我只是​​修正了語法。頭部xs導致問題,因爲您不檢查xs是否爲空。 –

+0

是的,我現在知道爲什麼我不能在'|'條件下使用'[a]'。感謝您的解釋。 –

2

我並不很清楚,什麼是你想檢查與表達x == [a],因爲[a]是一個型「a的名單」。讓我們嘗試實現的功能,使用矩陣的定義從維基:

A matrix is a rectangular array of numbers or other mathematical objects, for which operations such as addition and multiplication are defined.

因此,所有我們需要檢查的是,在基體中的所有行具有相同的尺寸。另請注意,有一個情況下,所謂的,空矩陣

In some contexts, such as computer algebra programs, it is useful to consider a matrix with no rows or no columns, called an empty matrix.

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