2009-11-17 3 views
15

Ich erinnere mich an eine ältere Version von F #, die strukturelle Dekomposition erlaubt, wenn Sequenzen genau wie Listen abgeglichen werden. Gibt es eine Möglichkeit, die Listen-Syntax zu verwenden, während die Sequenz faul bleibt? Ich hoffe, eine Menge Anrufe zu Seq.head und Seq.skip für wie etwas 1.Kann man mit zerlegten Sequenzen in F # übereinstimmen?

Ich hoffe, zu vermeiden:

let decomposable (xs:seq<'a>) = 
    match xs with 
    | h :: t -> true 
    | _ -> false 
seq{ 1..100 } |> decomposable 

Aber dies nur Griffe Listen und gibt einen Typ Fehler, wenn Sequenzen verwenden. Wenn Sie List.of_seq verwenden, scheint es alle Elemente in der Sequenz auszuwerten, auch wenn es unendlich ist.

Antwort

21

Wenn Sie den LazyList-Typ im PowerPack verwenden, verfügt er über aktive Muster namens LazyList.Nil und LazyList.Cons, die dafür hervorragend geeignet sind.

Der Typ seq/IEnumerable ist nicht besonders geeignet für Mustervergleiche. Ich kann LazyList nur wärmstens empfehlen. (Siehe auch Why is using a sequence so much slower than using a list in this example.)

let s = seq { 1..100 } 
let ll = LazyList.ofSeq s 
match ll with 
| LazyList.Nil -> printfn "empty" 
| LazyList.Cons(h,t) -> printfn "head: %d" h 
+5

Link hier für jeden, der (wie ich) nicht wusste, was das Netzteil ist: http://fsharppowerpack.codeplex.com/ – gatoatigrado

7

Seq funktioniert gut in aktiven Mustern! Es sei denn, ich etwas Schreckliches hier tue ...

let (|SeqEmpty|SeqCons|) (xs: 'a seq) = //' 
    if Seq.isEmpty xs then SeqEmpty 
    else SeqCons(Seq.head xs, Seq.skip 1 xs) 

// Stupid example usage 
let a = [1; 2; 3] 

let f = function 
    | SeqEmpty -> 0 
    | SeqCons(x, rest) -> x 

let result = f a 

Ich weiß nicht, wie Stackoverflow den Code markieren in F # Modus zu bekommen, ich denke, es ist mit OCaml hier so die allgemeine Anmerkung verrückt geht ...

+3

Ein Trick für Fälle, in denen Sie ein einzelnes Single-Quote möchten: Fügen Sie eine andere single- Zitat in einem Kommentar am Ende der Zeile: // ' – harms

+7

Es ist ein netter Trick, aber mehr als eine zuverlässige Quelle zeigt, dass es kein gutes Muster seit der Auswertung der Sequenz ist O (n^2): http: // stackoverflow com/questions/1306140/f-why-is-using-a-sequence-so-viel-langsamer-als-Verwenden-einer-Liste-in-diesem-Beispiel/1306267 # 1306267 – Juliet

+1

Richtig, aber das Beispiel des Fragestellers ist nicht rekursiv. Dies ist natürlich nicht gut für die Wiederholung der Sequenz, aber wenn Sie nur Muster auf dem Kopf oder etwas ... –

0

Denken Sie daran, Seq hat auch Funktionen zum Reduzieren von Karten, so dass Sie oft nur mit diesen umgehen können. In diesem Beispiel entspricht Ihre Funktion "Seq.isEmpty". Sie könnten versuchen, fsi zu starten und nur die Optionen zum Beenden der Tabs durchzugehen (geben Sie "Seq." Ein und drücken Sie die Tab-Taste); es könnte haben, was Sie wollen.

Verwandte Themen