sieve :: Int -> [Int]
sieve n = takeWhile lessThan (till n)
    where lessThan x = x<=n
          till n = removeUntil (intSqrt n) [2..]


--intSqrt :: Int -> Int
intSqrt x
        | x <=0 = 0
        | otherwise = maximum $ takeWhile square [1..x]
        where square y = y*y <= x

--removeUntil :: Int -> [Int] -> [Int]
removeUntil num list = tailremoveUntil num [] list

--tailremoveUntil :: Int -> [Int] -> [Int] -> [Int]
tailremoveUntil num header rest@(x:xs)
    | num >= x = tailremoveUntil num (x:header) (removeMults x xs)
    | otherwise = (reverse header) ++ rest
    
--removeMults :: Int -> [Int] -> [Int]
removeMults x xs = filter (notMultipleOf x) xs

--notMultipleOf :: Int -> (Int -> Bool)
notMultipleOf x = \y -> (y `mod` x) /= 0
