Generation of all numbers of arbitrary length and base
It turns out that this is exactly what replicateM does in the [] monad. For the sake of completeness, let's look at exactly how replicateM works.

replicateM :: Monad m =&gt; Int -&gt; m a -&gt; m [a]
replicateM n x = sequence (replicate n x)

replicate :: Int -&gt; a -&gt; [a]
replicate n x = [ x | _ &lt;- [1..n] ]


replicateM turns out to just pass off the heavy lifting to replicate and sequence. replicate is pretty simple, so the interesting part happens in sequence:

sequence :: Monad m =&gt; [m a] -&gt; m [a]
sequence [] = return []
sequence (x:xs) = do
    x'  &lt;- x
    xs' &lt;- sequence xs
    return (x' : xs')


And in fact, that's exactly what leaning on the [] monad instance for iteration looks like. A couple of binds and a return.