2011-04-20 7 views
10

posso fareSeq.iter vs per - che differenza?

for event in linq.Deltas do 

o posso fare

linq.Deltas |> Seq.iter(fun event -> 

Quindi non sono sicuro se questo è lo stesso. Se quello non è lo stesso voglio sapere la differenza. Non riesco a scegliere cosa usare: iter o for.

aggiunto - quindi se questo è l'aspetto della scelta preferisco usare iter ad un livello superiore e for è per Clousures

aggiunti alcuni tardi - cercando come iter è map + ignore - è la modo di correre usando la parola di ignoranza imperativa. Quindi sembra un modo funzionale ...

risposta

10

È possibile modificare le variabili mutabili dal corpo di un ciclo for. Non puoi farlo da una chiusura, il che implica che non puoi farlo usando iter. (Nota:.. Sto parlando di variabili mutabili dichiarate al di fuori della for/iter variabili mutabili locali sono accessibili)

Considerando che il punto di iter è quello di eseguire alcune effetto collaterale, la differenza può essere importante.

Io personalmente uso raramente iter, perché trovo che lo for sia più chiaro.

3

Per la maggior parte delle situazioni, sono uguali. Preferirei il primo utilizzo. Mi sembra chiaro.

La differenza è che for in anello di supporto IEnumerable oggetti, mentre Seq.iter richiede che la vostra collezione (linq.deltas) è IEnumerable<T>.

E.g. MatchCollection classe in .net espressione regolare eredita IEnumerable non IEnumerable<T>, non è possibile utilizzare Seq.map o Seq.iter direttamente su di esso. Ma puoi usare il ciclo for in.

+0

Si può ancora fare qualcosa di simile ss {for x in MatchCollection -> x} – manojlds

+1

o 'matchColl |> seq.cast |> Seq.iter' – ildjarn

+1

@ildjarn - vedi http://fssnip.net/ 4f per un'altra possibilità. – kvb

2

È lo stile di programmazione. Imperativo vs utilizzando la programmazione funzionale. Tieni presente che F # non è un puro linguaggio di programmazione funzionale.

Generalmente, utilizzare Seq.Iter se fa parte di alcune grandi elaborazioni di pipeline, in quanto ciò lo rende molto più chiaro, ma per il caso ordinario penso che la via principale sia più chiara. A volte è una preferenza personale, a volte sono altri problemi come le prestazioni.

1

for in F # è una forma di list comprehension - pane e burro di programmazione funzionale, mentre Seq.iter è un 'per gli effetti collaterali solo' costrutto imperativo - non un segno di un codice funzionale. Qui che cosa si può fare con for:

let pairsTo n = seq { 
    for i in [1..n] do 
     for j in [i..n] do 
      if j%i <> 0 then yield (i,j) } 

printf "%A" (pairsTo 10 |> Seq.toList) 
+3

Ci sono due diversi 'for' in F # - uno è all'interno delle list comprehensions (come dici tu) e l'altro è imperativo' for' che è abbastanza simile a 'Seq.iter'. –

17

Come altri hanno detto, ci sono alcune differenze (iter supporta non generico IEnumerator e si può mutare mutable valori in for).Queste sono a volte importanti differenze, ma la maggior parte delle volte puoi scegliere liberamente quale usare.

Generalmente preferisco for (se esiste un costrutto linguistico, perché non utilizzarlo?). I casi in cui iter sembra più bello sono quando si dispone di una funzione che è necessario chiamare (ad esempio utilizzando l'applicazione parziale):

// I would write this: 
strings |> Seq.iter (printfn "%c") 

// instead of: 
for s in strings do printfn "%c" s 

Allo stesso modo, utilizzando iter è più bello se lo si utilizza al fine di qualche pipeline di elaborazione:

// I would write this: 
inputs |> Seq.filter (fun x -> x > 0) 
     |> Seq.iter (fun x -> foo x) 

// instead of: 
let filtered = inputs |> Seq.filter (fun x -> x > 0) 
for x in filtered do foo x 
Problemi correlati