Sekwencje (F#)

A sekwencji jest logiczną szereg elementów wszystkich jednego typu.Sekwencje są szczególnie przydatne, gdy mają duże, uporządkowane zbierania danych, ale nie koniecznie oczekuje się za pomocą wszystkich elementów.Sekwencja poszczególne elementy są obliczane tylko jako wymagane, tak sekwencji może zapewnić lepszą wydajność niż lista, w sytuacjach, w których nie wszystkie elementy są używane.Sekwencje są reprezentowane przez seq<'T> typu, który jest aliasem dla IEnumerable.W związku z tym dowolne.NET Framework typu, który implementuje System.IEnumerable może być używany jako sekwencję.Moduł Seq zapewnia obsługę manipulacji na sekwencji.

Sekwencja wyrażeń

A wyrażenie sekwencji jest wyrażenie sekwencji.Sekwencja wyrażeń można podjąć liczba formularzy.Najprostszą formą określa zakres.Na przykład seq { 1 .. 5 } tworzy sekwencja, która zawiera pięć elementów, w tym punkty końcowe, 1 i 5.Można również określić przyrostu (lub zmniejszyć) między dwoma okresami podwójne.Na przykład poniższy kod tworzy sekwencji wielokrotności 10.

// Sequence that has an increment.
seq { 0 .. 10 .. 100 }

Sekwencja wyrażeń składają się z F# wyrażeń, które produkują wartości sekwencji.Mogą używać yield słowa kluczowego do wartości, które stają się częścią sekwencji produkcji.

Oto przykład.

seq { for i in 1 .. 10 do yield i * i }

Można użyć -> zamiast operatora yield, w którym to przypadku można pominąć do słowa kluczowego, jak pokazano w poniższym przykładzie.

seq { for i in 1 .. 10 -> i * i }

Poniższy kod generuje listę par współrzędnych wraz ze wskaźnikiem do tablicy, która reprezentuje siatki.

let (height, width) = (10, 10)
seq { for row in 0 .. width - 1 do 
         for col in 0 .. height - 1 do 
           yield (row, col, row*width + col)
    }

if Wyrażenie użyte w sekwencji jest filtr.Na przykład, aby wygenerować sekwencję tylko liczby Premier, przy założeniu, że funkcja isprime typu int -> bool, w następujący sposób utworzenia sekwencji.

seq { for n in 1 .. 100 do if isprime n then yield n }

Kiedy używać yield lub -> w iteracji, każdej iteracji oczekuje się wygenerować pojedynczy element w sekwencji.Jeśli każda iteracja wytwarza sekwencja elementów, użyj yield!.W takim przypadku elementy generowane w każdej iteracji są tak łączone, produkować końcowego sekwencji.

Można łączyć wiele wyrażeń razem w wyrażenie sekwencji.Elementy generowana przez wyrażenie każdego są łączone.Na przykład zobacz sekcję "Przykłady" tego tematu.

Przykłady

W pierwszym przykładzie użycia wyrażenie sekwencji, zawierającego iterację, filtr i wydajność do generowania tablicy.Ten kod drukuje sekwencji liczb Premier między 1 a 100 do konsoli.

// Recursive isprime function. 
let isprime n =
    let rec check i =
        i > n/2 || (n % i <> 0 && check (i + 1))
    check 2

let aSequence = seq { for n in 1..100 do if isprime n then yield n }
for x in aSequence do
    printfn "%d" x

Następujący kod dodaje do zastosowań yield do utworzenia tabeli mnożenia, która składa się z trzech elementów, krotek, każdy składający się z dwóch czynników i produktu.

let multiplicationTable =
  seq { for i in 1..9 do 
            for j in 1..9 do 
               yield (i, j, i*j) }

Poniższy przykład ilustruje użycie yield! do łączenia poszczególnych sekwencji do pojedynczego sekwencji końcowego.W tym przypadku sekwencji dla każdego poddrzewem w drzewie binarne są tak łączone, w funkcji rekurencyjnej produkować końcowego sekwencji.

// Yield the values of a binary tree in a sequence. 
type Tree<'a> =
   | Tree of 'a * Tree<'a> * Tree<'a>
   | Leaf of 'a

// inorder : Tree<'a> -> seq<'a>    
let rec inorder tree =
    seq {
      match tree with
          | Tree(x, left, right) ->
               yield! inorder left
               yield x
               yield! inorder right
          | Leaf x -> yield x
    }   

let mytree = Tree(6, Tree(2, Leaf(1), Leaf(3)), Leaf(9))
let seq1 = inorder mytree
printfn "%A" seq1

Za pomocą sekwencji

Sekwencje obsługuje wiele takie same funkcje jak zawiera listę.Sekwencje obsługuje także operacje takie jak grupowanie i Zliczanie przy użyciu funkcji generowania klucza.Sekwencje obsługuje również bardziej różnorodne funkcje ekstrahowania podciągów.

Wiele typów danych, takich jak listy, tablice, zestawów i mapy są niejawnie sekwencji, ponieważ są kolekcje agregującym.Funkcję, która zajmuje sekwencji jako argument działa z dowolnym F# typy danych, jako dodatek do wszelkich.NET Framework typ danych, który implementuje IEnumerable.Przeciwieństwem tego do funkcji, która przyjmuje listę jako argument, które mogą przyjmować tylko listy.Typ seq<'a> jest skrótem typu IEnumerable<'a>.Oznacza to, że dowolnego typu, który implementuje rodzajową IEnumerable, który zawiera tablice, list, ustawia i mapach F#, a także większości.NET Framework typy kolekcji, jest zgodny z seq typu i mogą być używane, tam, gdzie oczekuje sekwencji.

Funkcje modułu

Moduł Seq w obszaru nazw Microsoft.FSharp.Collections zawiera funkcje sekwencji.Te funkcje pracy z listy, tablice, mapy i jak również zestawy, ponieważ wszystkie te typy są agregującym i mogą być traktowane jako sekwencje.

Tworzenie sekwencji

Sekwencje można utworzyć przy użyciu wyrażeń sekwencji, opisane wcześniej lub za pomocą niektórych funkcji.

Pusty sekwencji można utworzyć za pomocą Seq.empty, lub można utworzyć sekwencji tylko jeden element określony za pomocą Seq.singleton.

let seqEmpty = Seq.empty
let seqOne = Seq.singleton 10

Można użyć Seq.init do utworzenia sekwencji, dla którego elementy są tworzone przy użyciu funkcji, które należy dostarczyć.Rozmiar jest również dostarczyć w sekwencji.Ta funkcja jest tak samo jak List.init, z wyjątkiem, że elementy nie są tworzone aż iterację sekwencji.Poniższy kod ilustruje użycie Seq.init.

let seqFirst5MultiplesOf10 = Seq.init 5 (fun n -> n * 10)
Seq.iter (fun elem -> printf "%d " elem) seqFirst5MultiplesOf10

Dane wyjściowe

0 10 20 30 40

Za pomocą Seq.ofArray i Seq.ofList<'T> — Funkcja (F#), można utworzyć sekwencji z list i tablic.Jednakże można także przekonwertować tablice i list do sekwencji za pomocą operatora rzutowania.Obie techniki są wyświetlane w poniższym kodzie.

// Convert an array to a sequence by using a cast. 
let seqFromArray1 = [| 1 .. 10 |] :> seq<int>
// Convert an array to a sequence by using Seq.ofArray. 
let seqFromArray2 = [| 1 .. 10 |] |> Seq.ofArray

Za pomocą Seq.cast, można utworzyć sekwencji z kolekcji lekko maszynowy, takie jak określono w System.Collections.Takie lekko maszynowy kolekcje mają typ elementu Object i są wyliczane za pomocą niepodstawowego IEnumerable typu.Poniższy kod ilustruje użycie Seq.cast do konwersji ArrayList w sekwencji.

open System
let mutable arrayList1 = new System.Collections.ArrayList(10)
for i in 1 .. 10 do arrayList1.Add(10) |> ignore
let seqCast : seq<int> = Seq.cast arrayList1

Sekwencje infinite można zdefiniować za pomocą Seq.initInfinite funkcji.Dla sekwencji możesz podać funkcję, która generuje każdego elementu z indeksu elementu.INFINITE sekwencji są możliwe z powodu oceny z opóźnieniem; elementy są tworzone w razie potrzeby przez wywołanie funkcji, który określisz.Poniższy przykład kodu daje ciąg przestawne numery punkt, w tym przypadku przemienne serii odwrotności kwadratów kolejnych liczb całkowitych.

let seqInfinite = Seq.initInfinite (fun index ->
    let n = float( index + 1 )
    1.0 / (n * n * (if ((index + 1) % 2 = 0) then 1.0 else -1.0)))
printfn "%A" seqInfinite

SEQ.unfold generuje sekwencji z funkcji obliczeń, która zajmuje się Państwo i przekształca go do produkcji każdego kolejnego elementu w sekwencji.Stan jest po prostu wartość, która jest używana do obliczania każdy element i można zmienić, ponieważ każdy element jest obliczana.Drugi argument Seq.unfold jest wartością początkową, który jest używany do uruchamiania sekwencji.Seq.unfoldużywa typu opcji dla Państwa, które umożliwia zakończenie sekwencji przywracając None wartości.Poniższy kod ilustruje dwa przykłady sekwencji, seq1 i fib, które są generowane przez unfold operacji.Pierwszy, seq1, jest po prostu proste sekwencji numerów do 100.Drugi, fib, korzysta z unfold do obliczenia sekwencji Fibonacciego.Ponieważ każdy element w sekwencji Fibonacciego jest suma dwóch poprzednich liczbach Fibonacciego, wartość stanu jest krotka, która składa się z dwóch poprzednich liczbach w sekwencji.Wartość początkowa jest (1,1), pierwsze dwie cyfry w sekwencji.

let seq1 = Seq.unfold (fun state -> if (state > 20) then None else Some(state, state + 1)) 0
printfn "The sequence seq1 contains numbers from 0 to 20." 
for x in seq1 do printf "%d " x
let fib = Seq.unfold (fun state ->
    if (snd state > 1000) then None
    else Some(fst state + snd state, (snd state, fst state + snd state))) (1,1)
printfn "\nThe sequence fib contains Fibonacci numbers." 
for x in fib do printf "%d " x

Produkcja jest w następujący sposób:

Seq1 sekwencji zawiera cyfry od 0 do 20.

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Fib sekwencji zawiera liczb Fibonacciego.

2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

Poniższy kod jest przykładem, korzystającej z wielu funkcji modułu sekwencji opisane tutaj do generowania i obliczyć wartości infinite sekwencji.Kod może zająć kilka minut.

// infiniteSequences.fs 
// generateInfiniteSequence generates sequences of floating point 
// numbers. The sequences generated are computed from the fDenominator 
// function, which has the type (int -> float) and computes the 
// denominator of each term in the sequence from the index of that 
// term. The isAlternating parameter is true if the sequence has 
// alternating signs. 
let generateInfiniteSequence fDenominator isAlternating =
    if (isAlternating) then
        Seq.initInfinite (fun index -> 1.0 /(fDenominator index) * (if (index % 2 = 0) then -1.0 else 1.0))
    else
        Seq.initInfinite (fun index -> 1.0 /(fDenominator index))

// The harmonic series is the series of reciprocals of whole numbers. 
let harmonicSeries = generateInfiniteSequence (fun index -> float index) false 
// The harmonic alternating series is like the harmonic series 
// except that it has alternating signs. 
let harmonicAlternatingSeries = generateInfiniteSequence (fun index -> float index) true 
// This is the series of reciprocals of the odd numbers. 
let oddNumberSeries = generateInfiniteSequence (fun index -> float (2 * index - 1)) true 
// This is the series of recipocals of the squares. 
let squaresSeries = generateInfiniteSequence (fun index -> float (index * index)) false 

// This function sums a sequence, up to the specified number of terms. 
let sumSeq length sequence =
    Seq.unfold (fun state ->
        let subtotal = snd state + Seq.nth (fst state + 1) sequence
        if (fst state >= length) then None
        else Some(subtotal,(fst state + 1, subtotal))) (0, 0.0)

// This function sums an infinite sequence up to a given value 
// for the difference (epsilon) between subsequent terms, 
// up to a maximum number of terms, whichever is reached first. 
let infiniteSum infiniteSeq epsilon maxIteration =
    infiniteSeq
    |> sumSeq maxIteration
    |> Seq.pairwise
    |> Seq.takeWhile (fun elem -> abs (snd elem - fst elem) > epsilon)
    |> List.ofSeq
    |> List.rev
    |> List.head
    |> snd

// Compute the sums for three sequences that converge, and compare 
// the sums to the expected theoretical values. 
let result1 = infiniteSum harmonicAlternatingSeries 0.00001 100000
printfn "Result: %f  ln2: %f" result1 (log 2.0)

let pi = Math.PI
let result2 = infiniteSum oddNumberSeries 0.00001 10000
printfn "Result: %f pi/4: %f" result2 (pi/4.0)

// Because this is not an alternating series, a much smaller epsilon 
// value and more terms are needed to obtain an accurate result. 
let result3 = infiniteSum squaresSeries 0.0000001 1000000
printfn "Result: %f pi*pi/6: %f" result3 (pi*pi/6.0)

Wyszukiwanie i znajdowanie elementów

Sekwencje obsługi funkcji dostępnych w przypadku list: Seq.exists, Seq.exists2, Seq.find, Seq.findIndex, Seq.pick, Seq.tryFind, i Seq.tryFindIndex.Wersje te funkcje, które są dostępne dla sekwencji oceny sekwencji do elementu, który jest poszukiwany.Przykłady, zobacz zawiera listę.

Uzyskiwanie podciągów

SEQ.Filter i Seq.choose są jak odpowiadające im funkcje, które są dostępne dla list, z wyjątkiem, że filtrowanie i wybieranie nie wystąpi, dopóki nie są obliczane elementy sekwencji.

SEQ.Truncate tworzy sekwencji z innej kolejności, ale ogranicza sekwencji do określonej liczby elementów.SEQ.Take powoduje utworzenie nowej sekwencji, który zawiera tylko określoną liczbę elementów od początku sekwencji.Jeśli istnieją mniejszej liczby elementów w kolejności niż określić podjęcie, Seq.take wyrzuca InvalidOperationException.Różnica między Seq.take i Seq.truncate jest to, że Seq.truncate nie wytwarzają błąd, jeśli liczba elementów jest mniejsza niż liczba można określić.

Poniższy kod pokazuje zachowanie i różnice między Seq.truncate i Seq.take.

let mySeq = seq { for i in 1 .. 10 -> i*i }
let truncatedSeq = Seq.truncate 5 mySeq
let takenSeq = Seq.take 5 mySeq

let truncatedSeq2 = Seq.truncate 20 mySeq
let takenSeq2 = Seq.take 20 mySeq

let printSeq seq1 = Seq.iter (printf "%A ") seq1; printfn "" 

// Up to this point, the sequences are not evaluated. 
// The following code causes the sequences to be evaluated.
truncatedSeq |> printSeq
truncatedSeq2 |> printSeq
takenSeq |> printSeq
// The following line produces a run-time error (in printSeq):
takenSeq2 |> printSeq

Dane wyjściowe, zanim wystąpi błąd, jest następująca:

1 4 9 16 25 
1 4 9 16 25 36 49 64 81 100 
1 4 9 16 25 
1 4 9 16 25 36 49 64 81 100

Za pomocą Seq.takeWhile, można określić funkcję predykatu (funkcja logiczna) i utwórz sekwencję z innym sekwencji składa się z tych elementów oryginalna kolejność, w którym orzeczenie jest true, ale zatrzymana przed pierwszym elementem, dla którego predykat zwraca false.SEQ.Skip zwraca sekwencja, która pomija określoną liczbę elementów pierwszego innego sekwencji i zwraca pozostałe elementy.SEQ.skipWhile zwraca sekwencja, która pomija pierwsze elementy innej kolejności, tak długo, jak długo predykat zwraca true, a następnie zwraca pozostałe elementy, począwszy od pierwszego elementu, dla którego predykat zwraca false.

Poniższy przykład kodu ilustruje zachowanie i różnice między Seq.takeWhile, Seq.skip, i Seq.skipWhile.

// takeWhile 
let mySeqLessThan10 = Seq.takeWhile (fun elem -> elem < 10) mySeq
mySeqLessThan10 |> printSeq

// skip 
let mySeqSkipFirst5 = Seq.skip 5 mySeq
mySeqSkipFirst5 |> printSeq

// skipWhile 
let mySeqSkipWhileLessThan10 = Seq.skipWhile (fun elem -> elem < 10) mySeq
mySeqSkipWhileLessThan10 |> printSeq

Wprowadza dane wyjściowe.

1 4 9 
36 49 64 81 100 
16 25 36 49 64 81 100 

Przekształcanie sekwencji

SEQ.Pairwise powoduje utworzenie nowej sekwencji, w którym sekwencji wejściowych kolejne elementy są grupowane w krotek.

let printSeq seq1 = Seq.iter (printf "%A ") seq1; printfn "" 
let seqPairwise = Seq.pairwise (seq { for i in 1 .. 10 -> i*i })
printSeq seqPairwise

printfn "" 
let seqDelta = Seq.map (fun elem -> snd elem - fst elem) seqPairwise
printSeq seqDelta

SEQ.windowed przypomina Seq.pairwise, z wyjątkiem, że zamiast produkujących sekwencja krotek, produkuje sekwencji tablic zawierających kopie elementów sąsiednich ( okna) z sekwencji numerów.Można określić numer sąsiadujących elementów, który ma w każdej tablicy.

Poniższy przykład kodu ilustruje użycie Seq.windowed.W tym przypadku liczba elementów w oknie jest 3.W przykładzie użyto printSeq, który jest zdefiniowany w poprzednim przykładzie kodu.

let seqNumbers = [ 1.0; 1.5; 2.0; 1.5; 1.0; 1.5 ] :> seq<float>
let seqWindows = Seq.windowed 3 seqNumbers
let seqMovingAverage = Seq.map Array.average seqWindows
printfn "Initial sequence: "
printSeq seqNumbers
printfn "\nWindows of length 3: "
printSeq seqWindows
printfn "\nMoving average: "
printSeq seqMovingAverage

Wprowadza dane wyjściowe.

Początkowy sekwencji:

1.0 1.5 2.0 1.5 1.0 1.5 

Windows of length 3: 
[|1.0; 1.5; 2.0|] [|1.5; 2.0; 1.5|] [|2.0; 1.5; 1.0|] [|1.5; 1.0; 1.5|] 

Moving average: 
1.5 1.666666667 1.5 1.333333333

Operacje z wielu sekwencji

SEQ.zip i Seq.zip3 podjąć dwa lub trzy sekwencje i produkują sekwencja krotek.Funkcje te są jak odpowiadające im funkcje dostępne dla zawiera listę.Nie istnieje żadne odpowiednie funkcje do oddzielenia sekwencji jednego do dwóch lub więcej sekwencji.Jeśli potrzebujesz tej funkcji dla sekwencji przekonwertować sekwencji do listy i używać List.unzip.

Sortowanie, porównywanie i grupowanie

Funkcje sortowania obsługiwane dla list także pracować z sekwencji.Obejmuje to Seq.sort i Seq.sortBy.Te funkcje iteracji całej sekwencji.

Porównanie dwóch sekwencji przy użyciu Seq.compareWith funkcji.Funkcja porównuje kolejnych elementów z kolei i przerywa działanie po napotkaniu pierwszego pary nierówne.Wszelkie dodatkowe elementy nie przyczyniają się do porównania.

Poniższy kod ilustruje wykorzystanie Seq.compareWith.

let sequence1 = seq { 1 .. 10 }
let sequence2 = seq { 10 .. -1 .. 1 }

// Compare two sequences element by element. 
let compareSequences = Seq.compareWith (fun elem1 elem2 ->
    if elem1 > elem2 then 1
    elif elem1 < elem2 then -1
    else 0) 

let compareResult1 = compareSequences sequence1 sequence2
match compareResult1 with
| 1 -> printfn "Sequence1 is greater than sequence2."
| -1 -> printfn "Sequence1 is less than sequence2."
| 0 -> printfn "Sequence1 is equal to sequence2."
| _ -> failwith("Invalid comparison result.")

W poprzednim kodzie pierwszy element jest obliczane i zbadane, a wynik jest równy -1.

SEQ.countBy ma funkcję, która generuje wartość o nazwie klucz dla każdego elementu.Klucz jest generowany dla każdego elementu, wywołując funkcję dla każdego elementu.Seq.countBynastępnie zwraca sekwencji, zawierającą wartości klucza, a licznik elementów, które są generowane każdej wartości klucza.

let mySeq1 = seq { 1.. 100 }
let printSeq seq1 = Seq.iter (printf "%A ") seq1; printfn "" 
let seqResult = Seq.countBy (fun elem -> if elem % 3 = 0 then 0
                                         elif elem % 3 = 1 then 1
                                         else 2) mySeq1

printSeq seqResult

Wprowadza dane wyjściowe.

(1, 34) (2, 33) (0, 33) 

Dane wyjściowe poprzedniego pokazuje zostały elementy 34 oryginalna kolejność, że produkowane klucza 1, 33 wartości, które produkowane klucz 2 i 33 wartości, które produkowane klawisz 0.

Można grupować elementy w sekwencji, wywołując Seq.groupBy.Seq.groupByTrwa sekwencji i funkcji, która generuje klucz od elementu.Funkcja jest wykonywana dla każdego elementu sekwencji.Seq.groupByZwraca sekwencja krotek, gdzie pierwszy element każdej krotki jest kluczem, a drugi jest sekwencja elementów, które wywołują ten klucz.

Poniższy przykład kodu pokazuje użycie Seq.groupBy partycji sekwencja liczb z zakresu od 1 do 100 na trzy grupy, które mają odrębną klucz wartości 0, 1 i 2.

let sequence = seq { 1 .. 100 }
let printSeq seq1 = Seq.iter (printf "%A ") seq1; printfn "" 
let sequences3 = Seq.groupBy (fun index ->
                                if (index % 3 = 0) then 0
                                  elif (index % 3 = 1) then 1
                                  else 2) sequence
sequences3 |> printSeq

Wprowadza dane wyjściowe.

(1, seq [1; 4; 7; 10; ...]) (2, seq [2; 5; 8; 11; ...]) (0, seq [3; 6; 9; 12; ...]) 

Można utworzyć sekwencja, która eliminuje zduplikowane elementy, wywołując Seq.distinct.Lub można użyć Seq.distinctBy, który ma funkcję generowania klucza, aby zostać wywołana dla każdego elementu.Sekwencja wynikowy zawiera elementy oryginalnej kolejności, które miały unikatowe klucze; później elementy, które produkują zduplikowany klucz do elementu wcześniejszych są odrzucane.

Poniższy przykład kodu ilustruje użycie Seq.distinct.Seq.distinctobrazuje generowania sekwencji, które reprezentują liczb binarnych, a następnie wykazujące, że tylko odrębne elementy są 0 i 1.

let binary n =
    let rec generateBinary n =
        if (n / 2 = 0) then [n]
        else (n % 2) :: generateBinary (n / 2)
    generateBinary n |> List.rev |> Seq.ofList

printfn "%A" (binary 1024)

let resultSequence = Seq.distinct (binary 1024)
printfn "%A" resultSequence

Poniższy kod demonstruje, Seq.distinctBy począwszy od sekwencji, który zawiera liczb ujemnych i dodatnich i używając funkcji wartości bezwzględnej jako funkcja generowania klucza.Wynikowy sekwencji brakuje wszystkich liczb dodatnich, które odpowiadają liczb ujemnych w sekwencji, ponieważ liczby ujemne pojawiają się wcześniej w sekwencji i dlatego są zaznaczone zamiast liczb dodatnich, mają taką samą wartość bezwzględna lub klucza.

let inputSequence = { -5 .. 10 }
let printSeq seq1 = Seq.iter (printf "%A ") seq1; printfn ""
printfn "Original sequence: "
printSeq inputSequence
printfn "\nSequence with distinct absolute values: " 
let seqDistinctAbsoluteValue = Seq.distinctBy (fun elem -> abs elem) inputSequence
seqDistinctAbsoluteValue |> printSeq

Tylko do odczytu i buforowanych sekwencji

SEQ.ReadOnly tworzy kopię tylko do odczytu w sekwencji.Seq.readonlyjest przydatne, gdy masz kolekcję odczytu i zapisu, takich jak tablica, i nie chcesz zmodyfikować oryginalny zbiór.Ta funkcja umożliwia zachowanie obudowania danych.W poniższym przykładzie utworzono typu, która zawiera tablicę.Właściwość udostępnia tablicy, ale zamiast zwracać tablicy, funkcja zwraca utworzony z tablicy przy użyciu sekwencji Seq.readonly.

type ArrayContainer(start, finish) =
    let internalArray = [| start .. finish |]
    member this.RangeSeq = Seq.readonly internalArray
    member this.RangeArray = internalArray

let newArray = new ArrayContainer(1, 10)
let rangeSeq = newArray.RangeSeq
let rangeArray = newArray.RangeArray
// These lines produce an error:  
//let myArray = rangeSeq :> int array 
//myArray.[0] <- 0 
// The following line does not produce an error.  
// It does not preserve encapsulation.
rangeArray.[0] <- 0

SEQ.Cache tworzy przechowywanych wersji sekwencji.Użyj Seq.cache w celu uniknięcia ponownej oceny sekwencji lub, gdy ma wiele wątków, które używają sekwencji, ale należy się upewnić, że każdy element jest przetwarzane tylko jeden raz.Jeśli sekwencja, która jest używana przez wiele wątków, może mieć jeden wątek, który wylicza i oblicza wartości oryginalne sekwencji i pozostałe wątki mogą użyć sekwencji buforowane.

Wykonywanie obliczeń na sekwencji

Proste operacje arytmetyczne są podobne do list, takie jak Seq.average, Seq.sum, Seq.averageBy, Seq.sumBy, i tak dalej.

SEQ.fold, Seq.reduce, i Seq.scan są jak odpowiadające im funkcje, które są dostępne dla list.Sekwencje obsługuje podzbiór pełnego odmiany te funkcje obsługi listy.Aby uzyskać dodatkowe informacje i przykłady, zobacz Listy (F#).

Zobacz też

Informacje

IEnumerable

Inne zasoby

Materiały referencyjne dotyczące języka F#

Typy F#