我的foldl
的具体问题是什么,导致它无法终止或生成输出?为什么当我将它重写为foldl时,我的筛没有终止?
首先我实现了素数筛。这不是最好的,但它工作得很好(例如)take 20 primesA
。
primesA :: [Integer]
primesA = sieve 2 []
sieve :: Integral a => a -> [a] -> [a]
sieve i [] = (i:) $ sieve (i + 1) $ map (*i) [i ..]
sieve i [email protected](h : t)
| i == h = sieve (i + 1) t
| otherwise = (i:) $ sieve (i + 1) $ unionIncreasing composites $ map (*i) [i ..]
unionIncreasing :: Ord a => [a] -> [a] -> [a]
unionIncreasing [] b = b
unionIncreasing a [] = a
unionIncreasing [email protected](ah:at) [email protected](bh:bt) | ah < bh = ah : at `unionIncreasing` b
| ah == bh = ah : at `unionIncreasing` bt
| otherwise = bh : a `unionIncreasing` bt
然后,我认为这将是更哈斯克尔-Y消除使用foldl
如下柜台i
。但这不是有效的。
primesB :: [Integer]
primesB = [2..] `differenceIncreasing` composites
composites :: [Integer]
composites = foldl f [] [2..]
where f [] i = map (*i) [i ..]
f [email protected](h:t) i | i == h = knownComposites
| otherwise = (h:) $ unionIncreasing t $ map (*i) [i ..]
differenceIncreasing :: Ord a => [a] -> [a] -> [a]
differenceIncreasing [] b = []
differenceIncreasing a [] = a
differenceIncreasing (x:xs) (y:ys) | x < y = x : xs `differenceIncreasing` (y:ys)
| x == y = xs `differenceIncreasing` ys
| otherwise = (x:xs) `differenceIncreasing` ys
它既不终止也不产生当我运行(例如)head primesB
任何输出。
据推测,ghci正在寻找无数次的素数倍数列表,以妄图获得列表头的价值。
但是,为什么它具体做到这一点?
sacundim的答案可以回答你的具体问题,但你可能想看看这个:https://gist.github.com/nisstyre56/4699275和论文http://www.cs.hmc.edu/~ oneill /论文/ Sieve-JFP.pdf – Wes 2013-04-29 06:26:12
@Wes - aha,谢谢! M.奥尼尔的论文第11页显示了我正在瞄准的筛子。我花了一点时间尝试自己做到这一点,但对我来说并不那么容易。现在我可以仔细研究它。 – minopret 2013-05-02 01:34:33