Write a function to extract a given number of randomly selected elements from a list
Your solution looks good to me, no reason to discourage using let as far as I know.

Tip: if you make the type randomFromList :: Int -&gt; [a] -&gt; StdGen -&gt; ([a], StdGen), then you can call it like this: main = getStdGen &gt;&gt;= print . randomFromList 7 ['A'..'Z']

Also, if the requirement is interpreted as selecting randomly without replacement, your version only needs slight modification (this also uses randomR rather than mod):

dropAt :: Int -&gt; [a] -&gt; [a]
dropAt k xs = take k xs ++ drop (k+1) xs

randomFromList :: Int -&gt; [a] -&gt; StdGen -&gt; ([a], StdGen)
randomFromList 0 _ generator = ([], generator)
randomFromList _ [] generator = ([], generator)
randomFromList toDo xs generator =
  let (index, generator') = randomR (0, length xs - 1) generator
      (otherNumbers, generator'') = randomFromList  (toDo -1) (dropAt index xs) generator'
  in  ((xs !! index) : otherNumbers, generator'')


See also this shuffle implementation for some attempt at optimisation.  (You could potentially solve the random selection by something like take n . shuffle.)