2014-09-22 7 views
7

Non riesco a capire perché ci sono due diverse strutture in Swift che sono quasi le stesse.SequenceOf e LazySequence: qual è la differenza e l'uso previsto?

  • SequenceOf non è pigro?
  • Quali sono gli usi previsti per ciascuno?

Edit: Penso di non capire ancora cosa sia "pigro" in sequenza significa ... F.e. prendere questo codice che utilizza SequenceOf che presumibilmente non è pigro:

func myMap<S: SequenceType, V>(source: S, 
     selector: S.Generator.Element -> V) -> SequenceOf<V> { 
     let seq = SequenceOf { 
     _ -> GeneratorOf<V> in 
     var gen = source.generate() 
     return GeneratorOf { 
      let v = gen.next() 
      println(v) 
      return v == nil ? nil : selector(v!) 
     } 
     } 
     return seq 
    } 

chiamiamolo con

let a = myMap([1, 2, 3], { $0 * 2 }) 
    var gen = a.generate() 
    let v1 = gen.next() 
    let v2 = gen.next() 

Esso stampa

opzionale (1)

opzionale (2)

Mi sembra pigro per me ...

Edit # 2:

Quando si utilizza carta su una sequenza pigro sembra essere avidamente valutare gli elementi in ogni caso:

struct TransientView<S: SequenceType> : SequenceType { 

    private let seq: S 

    init(_ seq: S) { 
     self.seq = seq 
    } 

    func generate() 
     -> GeneratorOf<S.Generator.Element> { 
      var g = seq.generate() 
      return GeneratorOf { 
       println("next") 
       return g.next() 
      } 
    } 
} 

let seq = lazy(map(TransientView([1, 2, 3]), { $0 * 2 })) 

stampe "prossimi" 4 volte ...

Modifica # 3. Ecco la mia opinione corrente: sarebbe sbagliato dire "SequenceOf non è pigro". È piuttosto "SequenceOf è esteso con non-pig .map, .filter, ecc". È del tutto possibile scrivere versioni lazy di map, filer, ecc che si applicherebbero a qualsiasi sequenza, incluso SequenceOf. Ma, Apple ha deciso di applicare il paradigma "pigro" non solo alle istanze di sequenze, ma anche agli elementi di sequenza, quindi se si dichiara la variabile di sequenza come pigra, viene utilizzato LazySequence e in quanto tali le estensioni sono pigre. Penso che questo sia un approccio sbagliato e la dichiarazione pigra non dovrebbe essere trasferita agli elementi - invece gli elementi dovrebbero essere tenuti pigri finché è possibile. È facile convertire i pigri in desiderosi, ma non è possibile diversamente.

risposta

12

SequenceOf non è pigro?

Corretto. Non è pigro. Ecco perché esistono le forme pigre.

Quali sono gli usi previsti per ciascuno?

Airpseed Velocity probabilmente ha la discussione più completa dei vari tipi. SequenceOf fornisce semplici modi per generare sequenze da una chiusura. Fornisce anche una sorta di "sequenza typecast" per convertire un tipo di sequenza in un altro.

LazySequence viene creato principalmente utilizzando la funzione lazy. Working at being lazy di Velocity della velocità dell'aria fornisce una bella introduzione. Il suo scopo è di evitare di generare elementi prima che siano effettivamente necessari, il che è particolarmente utile per sequenze infinite, ma è utile in ogni caso che potrebbe non essere necessario tutti gli elementi, e non sono banali da generare.

Ho già detto che dovresti leggere Airspeed Velocity se vuoi fare immersioni profonde su questa roba? Ma vale comunque la pena tenere a mente che abbiamo solo ciò che possiamo dedurre dalle intestazioni, ricavare dalle discussioni di Devforum e intuire da ciò che sappiamo di Swift. I tipi di livello inferiore non sono ancora ben documentati e non fanno parte di alcun documento "ufficiale" e sono stati modificati più volte rispetto ai beta. Quindi non è sempre facile sapere precisamente ciò che il team Swift intende per loro nelle versioni a venire. Questo è il meglio che conosciamo finora.


EDIT: Come faccio notare nei commenti, non v'è alcuna funzione map che prende e restituisce un LazySequence in 6.1b3. Esiste solo un metodo map su LazySequence. Ma possiamo costruirne uno se lo vogliamo, e forse lo aggiungeranno alla fine:

func map<S: SequenceType, U>(source: LazySequence<S>, transform: S.Generator.Element -> U) -> LazySequence<MapSequenceView<S, U>> { 
    return source.map(transform) 
} 
+1

Grazie, Velocità dell'Aria è la mia migliore amica ora! –

+0

Puoi spiegare la pigrizia della sequenza? - ancora non capisco ... Aggiornamento della domanda. –

+0

Quando si applica 'map' a una sequenza lenta, restituisce un nuovo generatore senza calcolare tutti i valori. Quando si applica 'map' a una sequenza non pigro, calcola immediatamente tutti i valori e restituisce una matrice. La mappa –