素数懒惰序列

时间:2011-03-23 11:41:53

标签: f#

我是F#的新手,我只是想知道是否有办法在F#中获得素数的延迟序列。

在Haskell中,我使用下一个代码:

primes :: [Integer]
primes = sieve[2..]
       where sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p > 0]

在F#中我可以检查数字是否为素数:

let isPrime (number : bigint) =
    match number with
        | _ -> seq { bigint(2) .. bigint(Math.Sqrt(float number))}
        |> Seq.exists (fun x -> if (number % x = bigint(0)) then true else false)
        |> not

但我不知道如何将其转换为懒惰序列。

3 个答案:

答案 0 :(得分:7)

请参阅this问题,了解许多答案,给出了F#中的延迟素数序列。

对于使用isPrime实现的天真解决方案(即我想你可能有兴趣了解如何从一般的过滤函数生成无限序列),试试这个:

let primes =
    Seq.initInfinite (fun i -> i + 2) //need to skip 0 and 1 for isPrime
    |> Seq.map (fun i -> bigint(i))
    |> Seq.filter isPrime

但是,您可能希望以不同的方式解决Project Euler Problem 3问题,方法是实现一个特定的数字因子,而不是将数字穷尽地用素数除以最大值。虽然你最终还是需要一个素数序列生成器来解决问题。

答案 1 :(得分:3)

如果您想模仿Haskell的懒惰,可以使用FSharp.PowerPack.dll中的LazyList类型。 LazyList.Cons(p,xs)是对应于Haskell中的p:xs的模式匹配。 consDelayed中的'延迟'是必要的,因为常规的LazyList.cons会过于渴望并且无限期(当然受到你的耐心限制)。

您可能还会发现this有趣的问题。这是F#的另一个Haskell主筛。

这是你在F#中的代码(不幸的是相当难看):

#r "FSharp.PowerPack.dll"

//A lazy stream of numbers, starting from x
let rec numsFrom x = LazyList.consDelayed x (fun () -> numsFrom (x+1I))

let rec sieve = function
    | LazyList.Cons(p,xs) ->
        LazyList.consDelayed p (fun () -> 
                xs |> LazyList.filter (fun x -> x%p <> 0I) |> sieve)
    | _ -> failwith "This can't happen with infinite lists"

let primes() = sieve (numsFrom 2I)

FSI中的输出示例:

> primes() |> Seq.take 14 |> Seq.toList;;
Real: 00:00:00.000, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
val it : System.Numerics.BigInteger list =
  [2I; 3I; 5I; 7I; 11I; 13I; 17I; 19I; 23I; 29I; 31I; 37I; 41I; 43I]

答案 2 :(得分:1)

我没有F#powerpack的解决方案

module Prime
    let isPrime n = 
        let bound = int (sqrt(float n))
        seq{2..bound}
        |> Seq.exists (fun x -> n % x = 0) 
        |> not
    let rec nextPrime n = 
        if isPrime (n + 1) then n + 1
        else nextPrime (n+1)
    let sequence = 
        Seq.unfold(fun n -> Some(n, nextPrime n)) 1