Собственно, суть в реализации unionAll
.minus
просто извлекает элементы из своего правильного аргумента один за другим, не подозревая (конечно, предполагается, что оба аргумента не уменьшаются).
Во-первых, давайте переписать его как
primes = 2 : ps
ps = 3 : t
t = minus [5,7..] (unionAll [[p*p, p*p+2*p..] | p <- ps])
-- primes !! 2 == ps !! 1 == head t
= minus [5,7..] (unionAll [[p*p, p*p+2*p..] | p <- (3 : t)])
= minus [5,7..] (unionAll ([9, 15..] : [[p*p, p*p+2*p..] | p <- t]))
Теперь unionAll
умный: он опирается на предположение (здесь факт), что в unionAll xs
он утверждает, что (map head xs)
неубывающий.
Как таковой, он знает он не должен сравнивать 9
ни с чем!Таким образом, он просто производит его безоговорочно (вы можете проверить его определение, чтобы проверить это самостоятельно):
= minus [5,7..]
(9 : union [15, 21..] (unionAll ........))
Таким образом, minus
имеет что-то для сравнения 5
и 7
с, и производит:
= 5 : 7 : minus [9,11..]
(9 : union [15, 21..] (unionAll ........))
Все это от знания только первого нечетного простого числа, 3
.