我正在尝试使用Haskell解决Project Euler上的第二个问题。问题是相当直接的 - 总和甚至斐波那契数字少于4000000.(我是强迫症,我正在暗示一个稍微修改过的函数 - 允许任意限制的函数)。
我的初始代码是:
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投放?
答案 0 :(得分:6)
(:)
的类型是
(:) :: a -> [a] -> [a]
如果您有模式匹配
euler2 limit (num1:num2)
名称num1
和num2
绑定到构造函数(:)
的相应参数(如果提供的参数是非空列表),因此num2
是一个列表其元素的类型为num1
。
如果你匹配
(num1:num2:[])
隐式括号
(num1 : (num2 : []))
现在num2 : []
与作为顶级(:)
的第二个参数的列表匹配,并且该匹配成功,将num2
绑定到第二个列表元素,如果提供的参数是一个包含两个元素的列表。