发生检查:无法构造infinte类型

时间:2017-03-15 15:04:49

标签: haskell

我正在尝试使用筛选方法构建所有素数的列表:

primes remNum =
  let i = head remNum
  in i : primes (filter (\(x) -> x mod i /= 0) (tail remNum))

我得到的错误是:

* Occurs check: cannot construct the infinite type:
    t ~ (a -> a -> a) -> t -> a1
  Expected type: [t]
    Actual type: [(a -> a -> a) -> t -> a1]
* In the first argument of `head', namely `remNum'
  In the expression: head remNum
  In an equation for `i': i = head remNum
* Relevant bindings include
    i :: t (bound at lib.hs:30:7)
    remNum :: [(a -> a -> a) -> t -> a1] (bound at lib.hs:29:8)
    primes :: [(a -> a -> a) -> t -> a1] -> [t] (bound at lib.hs:29:1)

我不明白为什么当[(a-> a -> a) -> t -> a1]绑定到i时,为什么remNum会绑定t,因为head :: [a] -> a肯定会暗示remNum::[t]

所以这个想法就是它提供了一个所有数字的惰性列表,然后基本上维护了一个已删除值的列表。

它将被称为:

numsFrom n = n : numsFrom (n + 1)
primes numsFrom 2

1 个答案:

答案 0 :(得分:2)

x mod i

不是你想要的。你想用

x `mod` i

第一个问题是,由于ix都来自列表,因此它们必须具有相同的类型。我们称之为X类型。什么是X?好吧,既然我们使用的是x mod,那么它应该以{{1​​}}的类型开头:

mod

由于其他"参数"是type X = (Integer -> Integer -> Integer) -> … ,其类型与i相同,我们最终得到:

x

这是一种无限型。

所以正确的解决方案是

type X = (Integer -> Integer -> Integer) -> X -> …

primes remNum =
  let i = head remNum
  in i : primes (filter (\(x) -> x `mod` i /= 0) (tail remNum))

或(与模式匹配)

primes remNum =
  let i = head remNum
  in i : primes (filter (\(x) -> mod x i /= 0) (tail remNum))