我正在尝试使用筛选方法构建所有素数的列表:
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
答案 0 :(得分:2)
x mod i
不是你想要的。你想用
x `mod` i
第一个问题是,由于i
和x
都来自列表,因此它们必须具有相同的类型。我们称之为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))