First of all it is always more readable to write code with guards, instead of if-then-else. All the extraneous parens are also distracting.
The standard transformation for the inefficient appending-at-end functions, like your
digits n | n < 10    = [n] 
         | otherwise = digits (quot n 10) ++ [mod n 10]
is to introduce an additional argument, where calling the old digits n ++ xs is the same as calling the new go n xs:
digits n = go n []   -- digits_old n ++ [] == go n []
   where
   go n next | n < 10    = n : next
             | otherwise = go (quot n 10) (mod n 10 : next)
--                            [a,b,c,...,x,y]         [z]
--                            [a,b,c,...,x]         [y,z]
Thus the digits being produced in the reversed order go one by one into the result list being built bottom-to-the-top in an accumulator parameter, resulting in the list  created in the correct order.