Haskell不评估Lazily takeWhile

D. *_*nes 5 primes haskell list-comprehension lazy-evaluation prime-factoring

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]
Run Code Online (Sandbox Code Playgroud)

这是我的代码.我想你猜对了我要做的事情:使用无限素数列表给定数字的素数因子列表.但是这段代码不会懒惰地评估.

当我使用ghci:l mycode.hs输入时primeFactors 24,结果是[2, 3(并且光标在那里不断闪烁)没有进一步的Prelude>提示.我认为那里有一个问题.我究竟做错了什么?

谢谢.

n. *_* m. 7

takeWhile永远不会终止复合参数.如果n是复合的,它没有素因子>= n,所以takeWhile只会坐在那里.

应用于takeWhile素数列表,然后使用n modx 过滤结果,如下所示:

primeFactors n = [x | x <- takeWhile (<= n) primes, n `mod` x == 0]
Run Code Online (Sandbox Code Playgroud)

(<=用于代替<最大正确性,因此素数的素因子将由该数字组成).

  • 区分"有限"(也称为终止)列表和仅具有有限数量元素的列表很重要.例如`1:2:3:[]`是有限的(终止)和`1:2:3:infiniteLoop`虽然它只有3个元素.所以列表理解不会终止,即使它只产生有限数量的元素; 并且`takeWhile`不会终止,因为条件永远不会变为`false`并且list参数(列表理解)不会终止. (2认同)