所以我决定玩弄 Haskell。我正在尝试解决 Project Euler 的第一个问题。以下是我的代码:
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 甚至不包含递归步骤。
这是怎么回事?为什么它会如此壮观地破裂?我错过了什么模式?(我有单元素列表、多元素列表和空列表吗?)
编辑:对于任何关心我最初在上面提供的解决方案(在 John 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