我正在尝试使用Haskell解决Project Euler上的第二个问题。这个问题相当简单 - 将平均斐波纳契数字加起来小于4000000.(我是强迫症,我在暗示一个稍微修改过的函数 - 一个允许任意限制的函数)。Haskell无法构造无限类型:a0 = [a0]
我最初的代码为:
euler2 limit (num1:num2)
|(num1>limit) = 0
|((num2>limit) && ((mod num1 2) == 0)) = num1
|(num2>limit) = 0
|(((mod num1 2) == 0) && ((mod num2 2) == 0)) = num1+num2+(euler2 limit [num1+num2,num1+num2+num2])
|((mod num1 2) == 0) = num1+(euler2 limit [num1+num2,num1+num2+num2])
|((mod num2 2) == 0) = num2+(euler2 limit [num1+num2,num1+num2+num2])
|otherwise = euler2 limit [num1+num2,num1+num2+num2]
euler2 limit [] = euler2 limit [1,2]
这将产生以下错误:
Occurs check: cannot construct the infinite type: a0 = [a0]
In the second argument of `(>)', namely `limit'
In the first argument of `(&&)', namely `(num2 > limit)'
In the expression: ((num2 > limit) && ((mod num1 2) == 0))
现在通过一些试验和错误,我已经意识到,它正试图强制转换num2
作为一个列表,和这个小小的变化:
euler2 limit (num1:num2:[]) | (num1 > limit) = 0
修复了这个问题。我的问题是为什么?发生了什么,为什么它拒绝将num1
和num2
作为Ints?
尝试添加一个明确的类型签名到你的euler2函数中:'euler2 :: Integer [Integer]'(或类似的东西......)。修复类型可能会导致更简单的错误消息。 – hugomg 2013-02-08 19:54:05
'num1'是一个'Int',你的问题是'num2'不是;它是'Ints'的列表。 – sabauma 2013-02-08 19:56:26
对,但明确指出:[]感觉像脏兮兮的黑客。有什么办法可以更优雅地执行这种事情吗?什么是“Haskell方式”? – 2013-02-08 19:58:58