The main problem is that `elem` traverses list and that is slow. It is better to use [`Data.Set`](http://hackage.haskell.org/package/containers-0.6.0.1/docs/Data-Set.html) or [`HashMap`](http://hackage.haskell.org/package/unordered-containers-0.2.9.0/docs/Data-HashMap-Strict.html) as this data structures allow sub-linear membership checking. <!-- language: haskell --> import qualified Data.Set as Set hamx :: [Integer] -> [Integer] -> [Integer] hamx ls = reverse . Set.toList . loop (Set.fromList ls) where loop res [] = res loop res (x:xs) | even x && Set.member (div x 2) res = loop (Set.insert x res) xs | mod x 3 == 0 && Set.member (div x 3) res = loop (Set.insert x res) xs | mod x 5 == 0 && Set.member (div x 5) res = loop (Set.insert x res) xs | otherwise = loop res xs Or a bit shorter (but less readable) version: import Data.List (foldl') import qualified Data.Set as Set hamx :: [Integer] -> [Integer] -> [Integer] hamx ls = reverse . Set.toList . loop (Set.fromList ls) where loop = foldl' (\res x -> if predicate res x then Set.insert x res else res) predicate res x = any (\y -> mod x y == 0 && Set.member (div x y) res) [2, 3, 5] --- Using [`IntSet`](http://hackage.haskell.org/package/containers-0.6.0.1/docs/Data-IntSet.html) instead of `Set` is several times faster, but [Daniel Fischer's solution](https://stackoverflow.com/a/12482407/147057) is still several orders of magnitude faster. I put a project with [criterion](http://hackage.haskell.org/package/criterion) benchmark [here](https://github.com/jorpic/playground/tree/master/hamming-numbers).