A bit closer to the original: bfs :: Eq a => (a -> [a]) -> a -> [a] bfs f s = concat $ takeWhile (not . null) levels where levels = foldr trim [] $ [s] : map (nub . (>>= f)) levels trim xs xss = xs : map (\\ xs) xss