【发布时间】:2016-12-14 02:34:18
【问题描述】:
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> 提示。我认为那里有问题。我做错了什么?
谢谢。
【问题讨论】:
-
请注意,列表
[x | x <- primes, 10 `mod` x == 0]不是[2,5],而是类似于2:5:infiniteLoop,因为在5之后将尝试无限多个素数x他们可能会通过测试。当然我们知道他们不会,但列表理解不知道这一点。然后takeWhile陷入循环。 -
@chi 是的,我知道这将是一个无限列表,谢谢。但我认为当谓词不再成立时,
takeWhile将停止评估无限列表。 -
不。它不是一个无限的列表。在那个
takeWhile上没有问题。试试takeWhile (<=10) [1..]和takeWhile (<=10) (1:2:5:let f n = f (n+1) in f 3)。这里[1..]是一个无限列表,而1:2:5:...不是——它是一个在其第三个元素之后具有未定义脊椎的列表。在无限列表中,take n list将始终返回,而当脊椎未定义时则不会。
标签: haskell list-comprehension primes lazy-evaluation prime-factoring