Approaching this task I'd follow "functional first" principle, then bother about performance. The solution may be as simple as:
let projectEuler7() = primes |> Seq.nth 10001
or a mere direct F# translation of original problem "Of sequence of prime numbers take 10001th member".
Now the problem is a bit simpler: effectively and lazily generate (a potentially infinite) sequence of prime numbers. Lets approach the derivative problem following the same "functional first" approach:
let rec primes =
Seq.cache <| seq { yield 2; yield! Seq.unfold nextPrime 3 }
// We do cache the results for performance as we reuse already found primes
and nextPrime n = if isPrime n then Some(n, n + 2) else nextPrime(n + 2)
// obvious; our only leftover problem is effectively determine if arbitrary n is prime
and isPrime n =
primes
|> Seq.tryFind (fun x -> n % x = 0 || x * x > n)
|> fun x -> x.Value * x.Value > n
// implement the obvious zero reminder condition amplified by square root limit
That's it! 8 lines of functional first code with not at all bad performance: on my modest laptop it delivers solution to the original problem in only 90ms. Functional-first RULEZ!Maybe few times slower, than your final code, but way far ahead by succinctness and clarity.