具有 BigInteger 索引的 F# 序列

F# sequences with BigInteger indices

我正在寻找一种类似于 F# 中的序列的类型,其中索引可以是大整数,而不是限于 int。有没有这样的东西? 我所说的“大整数索引”是指一种类型,它允许与此等价的东西:

let s = Seq.initInfinite (fun i -> i + 10I)

既然你想索引一个序列,我假设你想要一个以 BigInteger 作为索引的 Seq.item 版本。 F# 中没有内置类似的东西,但定义您自己的东西很容易:

open System.Numerics

module Seq =
    let itemI (index : BigInteger) source =
        source |> Seq.item (int index)

请注意,除非您计划创建长度超过 2,147,483,647 项的序列,否则不需要新类型,否则这可能不切实际。

用法:

let items = [| "moo"; "baa"; "oink" |]

items
    |> Seq.itemI 2I
    |> printfn "%A"   // output: "oink"

initInfiniteBigInteger 相当于

let inf = Seq.unfold (fun i -> let n = i + bigint.One in Some(n, n)) bigint.Zero
let biggerThanAnInt = inf |> Seq.skip (Int32.MaxValue) |> Seq.head // 2147483648

在我的机器上 运行 大约需要 2 分钟。

但是,我怀疑这是否有任何实际用途:-)除非您从某个已知值开始 > Int32.MaxValue 并很快停止(生成少于 Int32.MaxValue 项),这然后可以通过将 BigInt 索引偏移到 Int32 域来解决。

理论上,您可以使用与 BigIntegers 一起使用的函数来修改 Seq 模块以跳过/window / ... 项目数量 > Int32.MaxValue(例如通过重复执行相应的Int32 变体)

以下将生成无限系列的 bigints:

let s = Seq.initInfinite (fun i -> bigint i + 10I)

我怀疑你真正想要的是 Map<'Key, 'Value>

这使您可以有效地使用 bigint 作为索引来查找您关心的任何值:

let map = 
    seq {
        1I, "one"
        2I, "two"
        3I, "three"
    }
    |> Map.ofSeq

// val map : Map<System.Numerics.BigInteger,string> =
//   map [(1, "one"); (2, "two"); (3, "three")]

map.TryFind 1I |> (printfn "%A") // Some "one"
map.TryFind 4I |> (printfn "%A") // None