簡體   English   中英

Haskell初學者,遞歸函數,列表,錯誤:非窮盡模式

[英]Haskell Beginner, recursive function, list, Error: Non-exhaustive patterns

我嘗試編寫一個函數[int]-> int以計算具有迭代函數的整數列表的總和(結果應等於內置函數sum)

19>sumList :: [Int] -> Int
20>sumList [list] | length[list] > 0  = [list]!!0 + sumList (drop 1 [list])
21>               | otherwise = 0

如果我嘗試運行它,這就是結果

uebung1.lhs:20:2: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘sumList’:
    Patterns not matched:
        []
        (_:_:_)
Ok, modules loaded: Main.
*Main> sumList []
*** Exception: uebung1.lhs:(20,2)-(21,31): Non-exhaustive patterns in     function sumList

*Main> sumList [3]
*** Exception: uebung1.lhs:(20,2)-(21,31): Non-exhaustive patterns in   function sumListi i i i i 

我做錯了什么? 我已經睡了一個晚上,但我只是不知道問題出在哪里。 受保護的等式應包含列表長度的所有情況。 感謝您的任何建議。

問題在於您的模式僅匹配具有一個元素的列表。

例如,如果您嘗試在ghci定義一個函數:

a [x] = x

然后嘗試使用元素數量不同的列表來調用它:

a [1]結果為1

a []結果與以下Exception: <interactive>:5:1-13: Non-exhaustive patterns in function a

a [1,2]結果,但Exception: <interactive>:1:1-9: Non-exhaustive patterns in function a

以下修改使您的功能正常運行:

sumList :: [Int] -> Int
sumList list | length list > 0  = list!!0 + sumList (drop 1 list)
             | otherwise = 0

但是,當然,以下定義會更慣用和更有效:

sumList :: [Int] -> Int
sumList [] = 0
sumList (x:xs) = x + sumList xs

通過(x:xs)模式,您會立即收到x作為列表的頭( list!!0 )和xs作為list!!0的頭( drop 1 list )。

該功能不適用於空白列表或包含多個項目的任何列表。

您的問題是,您要與[list]匹配,這是一個成員為list 相反,請嘗試僅匹配list 這意味着它將與您類型簽名中類型為[Int]任何內容匹配。

我很困惑,因為[a]類型適用於任何長度的列表,但是[a]僅匹配一個元素的列表。

我還附加了使用模式匹配編寫函數的另一種方法,希望對您有用。

sumList :: [Int] -> Int
sumList [] = 0
sumList (x:xs) = x + sumList xs

使用防護罩是很不尋常的,但是您做到了,您的代碼如下所示:

sumList :: [Int] -> Int
sumList list
    | length list > 0 = head list + sumList (tail list)
    | otherwise = 0

注意[list]是如何由list!! 0替換的!! 0 !! 0替換為headdrop 1替換為tail

Hoogle是您的朋友!

您也可以將空列表的支票移至第一名警衛,如下所示:

sumList :: [Int] -> Int
sumList list
    | list == [] = 0
    | otherwise = head list + sumList (tail list)

請注意,此代碼與模式匹配代碼有多相似。

其他人已經回答了,但是我想強調一點,編譯器發出的警告指出了問題所在:

Pattern match(es) are non-exhaustive
In an equation for ‘sumList’:
    Patterns not matched:
        []
        (_:_:_)

這就是說該代碼在其模式匹配中未處理某些情況。 上面的空列表[]被報告為不匹配,這意味着程序將在空列表上崩潰。 另外,格式(_:_:_)的列表不匹配:這些列表至少包含兩個元素,例如1:2:rest ,這是一個從元素12並隨后進行列表rest列表下一個元素。

因此,警告告訴我們,我們僅處理長度為1的列表。 實際上,我們只處理模式[_] ,它與_:[]相同-列表從一個元素開始,然后到那里結束。

如果您是初學者,我認為您還沒有學習模式匹配。 這應該是您學習Haskell的優先事項:這是最重要的功能之一。 一般來說,如果您的遞歸代碼使用length, !!, tail, head ,則很可能您做錯了。 在某些地方需要這些功能,但在許多簡單的練習中卻不需要這些功能,模式匹配通常是足夠而優雅的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM