Haskell不能构造无限类型:a0 = [a0]

时间:2013-02-08 19:48:32

标签: haskell

我正在尝试使用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

解决了这个问题。我的问题是为什么?发生了什么事,为什么拒绝将num1num2作为Ints投放?

1 个答案:

答案 0 :(得分:6)

(:)的类型是

(:) :: a -> [a] -> [a]

如果您有模式匹配

euler2 limit (num1:num2)

名称num1num2绑定到构造函数(:)的相应参数(如果提供的参数是非空列表),因此num2是一个列表其元素的类型为num1

如果你匹配

(num1:num2:[])

隐式括号

(num1 : (num2 : []))

现在num2 : []与作为顶级(:)的第二个参数的列表匹配,并且该匹配成功,将num2绑定到第二个列表元素,如果提供的参数是一个包含两个元素的列表。