Replacing an F# loop over a mutable variable by an immutable approach Consider:

        let mutable m' = m
        while m' % i = 0L do
            m' &lt;- m' / i


I've refactored it into:

        let m' =
            let rec exhaust m =
                if m % i = 0L then exhaust (m/i)
                else m
            exhaust m


but it's pretty obvious to me that the original code was way more concise and clear than this last one. Is there anything simple and clear that I'm missing regarding this refactor?

The full algorithm:

(* Calculates all the prime factors of a given integer *)
let primeFactors x =
    let rec primeFactors' = function
        | (m, _, r) when m = 1L -&gt; r
        | (m, i, r) -&gt;
            let mutable m' = m
            while m' % i = 0L do
                m' &lt;- m' / i
            primeFactors' (m', (i+1L), (if m &lt;&gt; m' then i::r else r))
    List.rev (primeFactors' (x, 2L, []))
I would write it this way

let rec exhaust m i =
    match m % i with
    | 0L -&gt; exhaust (m / i) i
    | _ -&gt; m


Not a huge improvement, but I think it's idiomatic. Now let's look at primeFactors:

let primeFactors x =
    let rec primeFactors' = function
        | (m, _, r) when m = 1L -&gt; r
        | (m, i, r) -&gt;
            let m' = exhaust m i
            primeFactors' (m', (i+1L), (if m &lt;&gt; m' then i::r else r))
    List.rev (primeFactors' (x, 2L, []))


Let's get rid of the when:

let primeFactors x =
    let rec primeFactors' = function
        | (1L, _, r) -&gt; r
        | (m, i, r) -&gt;
            let m' = exhaust m i
            primeFactors' (m', (i+1L), (if m &lt;&gt; m' then i::r else r))
    List.rev (primeFactors' (x, 2L, []))


And tidy up a little

let primeFactors x =
    let rec primeFactors' = function
        | 1L, _, r -&gt; r
        | m, i, r -&gt;
            let m' = exhaust m i
            primeFactors' (m', i + 1L, if m &lt;&gt; m' then i::r else r)
    primeFactors' (x, 2L, []) |&gt; List.rev


I know the style in F# is for short variable names, and I'm all for that for the most part, but I think in this case we can/should make them a bit clearer.

let rec exhaust n factor =
    match n % factor with
    | 0L -&gt; exhaust (n / factor) factor
    | _ -&gt; n

let rec primeFactors' = function
    | 1L, _, factors -&gt; factors
    | n, factor, factors -&gt;
        let m = exhaust n factor
        primeFactors' (m, factor + 1L, if n &lt;&gt; m then factor::factors else factors)

let primeFactors n =
    primeFactors' (n, 2L, []) |&gt; List.rev