內置的F#列表類型不具有任何長度緩存和沒有辦法增加,在一些巧妙的方式,所以你需要定義自己的類型。我認爲爲現有的F#list
類型編寫封裝器可能是最佳選擇。
這樣,就可以避免顯式轉換 - 當你包的列表中,它實際上並不會複製它(如在svick的實現),但包裝可以很容易地緩存Length
屬性:
open System.Collections
type LengthList<'T>(list:list<'T>) =
let length = lazy list.Length
member x.Length = length.Value
member x.List = list
interface IEnumerable with
member x.GetEnumerator() = (list :> IEnumerable).GetEnumerator()
interface seq<'T> with //'
member x.GetEnumerator() = (list :> seq<_>).GetEnumerator()
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module LengthList =
let ofList l = LengthList<_>(l)
let ofSeq s = LengthList<_>(List.ofSeq s)
let toList (l:LengthList<_>) = l.List
let length (l:LengthList<_>) = l.Length
的使用包裝器的最佳方式是使用LengthList.ofList
從標準F#列表創建LengthList
,並在使用標準List
模塊的任何功能之前使用LengthList.toList
(或只是List
)屬性。
但是,這取決於你的代碼的複雜性 - 如果你只需要幾個地方的長度,那麼它可能更容易分開保存並使用元組list<'T> * int
。
嗯...我猜列表不是這種情況下正確的數據結構。列表對於一些有限的值是可以接受的,但是如果這些值數量變得越來越大,您將會遇到性能問題。 – Ankur