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

标签 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 转换为 Int?

最佳答案

(:) 的类型是

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

如果您有模式匹配

euler2 limit (num1:num2)

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

如果你匹配

(num1:num2:[])

隐含括号

(num1 : (num2 : []))

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

关于Haskell 无法构造无限类型 : a0 = [a0],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14780214/

相关文章:

windows - 无法让 cabal 在 Windows 上找到 haskell-mpi 的 mpi 库

haskell - 执行 Monadic 计算 N 次

haskell - 类中的种类多态性

haskell - 在 Haskell 中定义函数的正确方法

Haskell:为什么这个函数不断要求用户输入而不终止

haskell - 使用 yesod 从 ajax 请求中获取数据很热

lighttpd 上的 haskell fastCGI,需要配置帮助

haskell - 了解 GHC 汇编输出

performance - 推理 Haskell 的性能

multithreading - Haskell:为什么 `par` 是这样定义的?