Вы можете сослаться на мой F # для Project Euler Wiki :
Я получил эту первую версию:
let isPrime n =
if n=1 then false
else
let m = int(sqrt (float(n)))
let mutable p = true
for i in 2..m do
if n%i =0 then p <- false
// ~~ I want to break here!
p
let rec nextPrime n =
if isPrime n then n
else nextPrime (n+1)
let problem7 =
let mutable result = nextPrime 2
for i in 2..10001 do
result <- nextPrime (result+1)
result
В этой версии, хотя выглядит лучше, но яеще не рано разрывать цикл, когда число не простое.В модуле Seq методы Существуют и Форалл поддерживают раннюю остановку:
let isPrime n =
if n<=1 then false
else
let m = int(sqrt (float(n)))
{2..m} |> Seq.exists (fun i->n%i=0) |> not
// or equivalently :
// {2..m} |> Seq.forall (fun i->n%i<>0)
Обратите внимание, что в этой версии isPrime функция наконец-то математически корректна, проверяя числа ниже 2.
Или вы можете использоватьхвостовая рекурсивная функция для выполнения цикла while:
let isPrime n =
let m = int(sqrt (float(n)))
let rec loop i =
if i>m then true
else
if n%i = 0 then false
else loop (i+1)
loop 2
Более функциональная версия задачи7 - использовать Seq.unfold для генерации бесконечной простой последовательности и взять n-й элемент этой последовательности:
let problem7b =
let primes =
2 |> Seq.unfold (fun p ->
let next = nextPrime (p+1) in
Some( p, next ) )
Seq.nth 10000 primes