2009-11-17 16 views
15

Mi sembra di ricordare una versione precedente di F # che consente la scomposizione strutturale quando si confrontano le sequenze come le liste. C'è un modo per usare la sintassi delle liste mantenendo la sequenza pigra? Sto sperando di evitare un sacco di chiamate a Seq.head e Seq.skip 1.È possibile abbinare le sequenze decomposte in F #?

spero in qualcosa di simile a:

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

Ma questo si occupa solo elenchi e dà un errore di tipo quando usando le sequenze. Quando si utilizza List.of_seq, sembra valutare tutti gli elementi della sequenza, anche se è infinito.

risposta

21

Se si utilizza il tipo LazyList nel PowerPack, dispone di modelli attivi denominati LazyList.Nil e LazyList.Cons che sono grandi per questo.

Il tipo seq/IEnumerable non è particolarmente adatto alla corrispondenza del modello; Consiglio vivamente LazyList per questo. (Vedi anche 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

collegamento qui per chiunque (come me) non sapeva che cosa è il power pack: http://fsharppowerpack.codeplex.com/ – gatoatigrado

7

Seq funziona correttamente in schemi attivi! A meno che non sto facendo qualcosa di orribile qui ...

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 

non so come ottenere il codice di StackOverflow evidenziando in modalità F #, credo che sia usando OCaml qui così l'annotazione generica va strambo ...

+3

Un trucco per le istanze in cui si desidera una singola citazione singola: aggiungere un'altra singola- citare in un commento alla fine della riga: // ' – harms

+7

È un trucco accurato, ma più di una fonte affidabile indica che non è un buon modello dal momento che la valutazione della sequenza è O (n^2): http: // stackoverflow .com/questions/1306140/f-why-is-using-a-sequence-so-very-slow-than-using-a-list-in-this-example/1306267 # 1306267 – Juliet

+1

Vero, ma l'esempio del questionario è non ricorsivo. Ovviamente non è un buon modo per ricominciare la sequenza, ma se vuoi semplicemente abbinare il pattern sulla testa o qualcosa del genere ... –

0

Ricorda che il seq ha anche funzioni di riduzione delle mappe, quindi potresti spesso riuscire a farla franca solo con quelle. Nell'esempio, la tua funzione è equivalente a "Seq.isEmpty". Potresti provare a lanciare fsi e solo scorrere le opzioni di completamento della scheda (inserisci "Seq." E premi scheda molto); potrebbe avere quello che vuoi.

Problemi correlati