我需要一个在F#中产生素数的函数。我发现了这个:
let primesSeq =
let rec nextPrime n p primes =
if primes |> Map.containsKey n then
nextPrime (n + p) p primes
else
primes.Add(n, p)
let rec prime n primes =
seq {
if primes |> Map.containsKey n then
let p = primes.Item n
yield! prime (n + 1) (nextPrime (n + p) p (primes.Remove n))
else
yield n
yield! prime (n + 1) (primes.Add(n * n, n))
}
prime 2 Map.empty
这非常有效,但有时我也需要使用int64 / BigInts。是否有一种更巧妙的方法来重用此代码而不是提供其他类似的序列:
let primesSeq64 = Seq.map int64 primesSeq
let primesBigInts = Seq.map (fun (x : int) -> BigInteger(x)) primesSeq
我听说过使用" inline"修改代码和" LanguagePrimitives",但我发现的所有内容都与函数有关,而我的问题与某个值有关。
此外 - 我希望有一个适用于整数类型的函数,并计算平方根的底数。
let inline sqRoot arg = double >> Math.Sqrt >> ... ?
但是我无法看到一种返回与#34; arg"相同类型的方法。是,因为Math.Sqrt返回一个double。再说一次 - 有没有比重新实现自己计算平方根的逻辑更好的了?
答案 0 :(得分:4)
因此,执行此操作的一般方法需要函数和语言原型 - 在您的情况下,只要1
编写LanguagePrimitives.GenericOne
,就会生成1
或1.0
等等。根据需要。
要使其工作,您需要创建一个函数值 - 您可以通过执行以下操作来避免这种情况:
let inline primesSeq() = ...
let primesintSeq = primesSeq() //if you use this as an int seq later the compiler will figure it out, otherwise you use
let specified : int seq = primesSeq()
我对sqrt案例不太确定 - 这可能取决于你是否愿意做出解决方案。
答案 1 :(得分:2)
通用sqRoot
的天真实现可能会遵循以下几点:
let sqRoot arg =
let inline sqrtd a = (double >> sqrt) a
let result = match box(arg) with
| :? int64 as i -> (sqrtd i) |> int64 |> box
| :? int as i -> (sqrtd i) |> int |> box
// cases for other relevant integral types
| _ -> failwith "Unsupported type"
unbox result
然后,检查FSI:
> let result: int = sqRoot 4;;
val result : int = 2
> let result: int64 = sqRoot 9L;;
val result : int64 = 3L