primeSieve n = sieve 3 (listArray (1, n) (False : True : cycle [True, False]) :: UArray Integer Bool)
where sieve i a
| i > limit = a
| a ! i = sieve (i + 1) a'
| otherwise = sieve (i + 1) a
where a' = a // zip [i * i, i * i + 2 * i .. n] (repeat False)
limit = floor (sqrt (fromInteger n))