isqrt :: Integer -> Integer
isqrt = floor . sqrt . fromIntegral
primes :: [Integer]
primes = sieve [2..] where
sieve (p:ps) = p : sieve [x | x <- ps, x `mod` p > 0]
primeFactors :: Integer -> [Integer]
primeFactors n = takeWhile (< n) [x | x <- primes, n `mod` x == 0]
这是我的代码。我想你已经猜到我的意图:使用无限的质数列表,给定一个数字的质因数列表。但是这个代码并不是惰性求值。
当我使用
ghci
,输入:l mycode.hs
和primeFactors 24
时,结果是 [2, 3
(光标一直闪烁在那里),没有更进一步的 Prelude>
提示。我认为那里有问题。我做错了什么?谢谢。
mod
x == 0]”不是“[2,5]”,而更像是“2:5:infiniteLoop”,因为在5之后会无限尝试可能通过测试的素数x。当然,我们知道它们不会通过测试,但是列表推导式不知道。然后,takeWhile
被卡在循环中。 - chitakeWhile
在断言不再成立时会停止评估无限列表。 - D. JonestakeWhile
没有问题。尝试执行takeWhile (<=10) [1..]
和takeWhile (<=10) (1:2:5:let f n = f (n+1) in f 3)
。其中[1..]
是无限列表,而1:2:5:...
不是 -- 它是一个具有未定义脊柱的列表,在其第三个元素后。在无限列表中,take n list
总是返回结果,但当脊柱未定义时不会返回。 - chi