2
所以我決定玩弄Haskell。我試圖解決項目歐拉的第一個問題。以下是我的代碼:Haskell生成非詳盡模式錯誤
euler1 limit (div:divisors) = if limit > 1 then (euler1 limit divisors) + (euler1 limit (div:[])) + (euler1 (limit-1) (div:divisors)) else 0
euler1 limit (divisor:[]) = if limit > 1 && (mod limit divisor) == 0 then limit else 0
euler1 limit [] = 0
然而,當我通過ghci中運行它,會發生以下情況:
euler1 9 [3,5]
*** Exception: <interactive>:3:5-90: Non-exhaustive patterns in function euler1
進一步調試:
euler1 5 []
0
euler1 5 [5]
*** Exception: <interactive>:3:5-90: Non-exhaustive patterns in function euler1
這表明,斷碼是在第二種情況下(帶有一個元素的列表),其中euler1甚至不包含遞歸步驟。
怎麼回事?爲什麼它會如此壯觀地破碎?我錯過了什麼樣的模式? (我有一個元素列表,多元素的列表,而空單沒有?)
編輯:任何人誰在乎我最初上面提供的解決方案(與約翰LS輝煌的幫助)仍然是不完全正確,因爲它會計算多於一個除數多於一次的項目。最後的正確的工作算法如下:
euler1 limit (divisor:[]) = if ((limit > 1) && ((mod limit divisor) == 0)) then limit else 0
euler1 limit (div:divisors) | ((limit > 1) && (euler1 limit (div:[]))==0) = (euler1 limit divisors) + (euler1 (limit-1) (div:divisors)) | ((limit > 1) && (euler1 limit (div:[]))/=0) = (euler1 limit (div:[])) + (euler1 (limit-1) (div:divisors)) |limit > 1 = euler1 (limit-1) (div:divisors) | otherwise = 0
euler1 limit [] = 0
謝謝!我從來沒有找到這個! (我相當肯定我有條件/ mod調用時出現了某種語法錯誤)xD –
@AbrahamP真的很值得在一個文件中保存你的函數,Euler.hs,並且執行:l在ghci中加載Euler.hs來加載它,比直接在ghci中編寫要容易得多。 – AndrewC
@AndrewC我同意,這就是我幾乎總是工作的方式。但是多線符號在其他情況下非常方便,並且它不是廣爲人知的,所以我藉此機會宣傳它。 –