I wrote a smooth function that returns a list of all smooth numbers below a certain limit from a list of prime:
repeatMul init limit = takeWhile (<=limit) . scanl (*) init . repeat
smooth limit = (`inner` 1)
where inner [] init = [init]
inner (x:xs) init = repeatMul init limit x >>= inner xs
For instance:
main = print . sort . smooth 20 $ [2, 3, 5]
-- [1,2,3,4,5,6,8,9,10,12,15,16,18,20]
It works fine, but I wonder if the inner function could be written in a different way. I've been trying to find a high order function to achieve the same purpose, but I can't wrap my head around it.
Also I'm new to haskell, so any general comment is welcome.
Extra question: I have another version of smooth that returns a set instead of a list:
import Data.Set (singleton, unions)
repeatMul limit x = takeWhile (<=limit) . iterate (*x)
smooth limit xs = foldr f singleton xs $ 1
where f x c = unions . map c . repeatMul limit x
Is it possible to simplify this as well even though the Set type does not instantiate the Monad type class?