2011-09-07 20 views
15

qualcuno può fornire alcuni esempi di comeScala Vector piega la sintassi (/: e: e /: )

/::\ and /:\

realtà abituarsi? Presumo che siano scorciatoie per i metodi riduci/piega, ma non ci sono esempi su come vengano effettivamente utilizzati nei documenti di Scala e sono impossibili da cercare su StackOverflow.

+0

Nota anche come piega a sinistra (piega), piega a destra (piega) e piega qualsiasi (??). Wikipedia ha alcune informazioni generali e belle immagini su [fold hofs] (http://en.wikipedia.org/wiki/Fold_%28higher-order_function%29). –

risposta

10

/: è un sinonimo di foldLeft e :\ per foldRight.

Ma ricorda che : si applica all'oggetto a destra di esso /:.

si Supponendo sanno che (_ * _) è una funzione anonima che è equivalente a (a, b) => a * b, e la firma di foldLeft e foldRight sono

def foldLeft [B] (z: B)(f: (B, A) ⇒ B): B 
def foldRight [B] (z: B)(f: (A, B) ⇒ B): B 

vale a dire che sono funzioni al curry che assumono un valore iniziale e una funzione che unisce il valore iniziale/accumulatore con un elemento dall'elenco, alcuni esempi sono:

List(1,2,3).foldLeft(1)(_*_) 

che è la stessa come

(1 /: List(1,2,3))(_*_) 

E

List(1,2,3).foldRight(1)(_*_) 

in notazione infissa è

(List(1,2,3) foldRight 1)(_*_) 

, che è lo stesso di

(List(1,2,3) :\ 1)(_*_) 

Aggiungi le tue raccolte e funzioni e godere!

La cosa da ricordare con il corto (/: e :\) notazioni è che, perché si sta utilizzando i notazione infissa è necessario mettere parentesi intorno alla prima parte in modo che esso per prendere la seconda lista di argomenti in modo corretto. Inoltre, ricorda che le funzioni di foldLeft e foldRight sono opposte, ma ha senso se stai visualizzando la piega nella tua testa.

+0

Hai dimenticato di dire, '/: \' è un sinonimo di 'fold', che è per il folding quando non ti interessa l'ordine. La sintassi è come per ': \'. Non l'ho mai usato, ma penso che sia utile per le raccolte parallele, quindi puoi dividere un'operazione a piega tra diversi thread/attori. –

3

Rex Kerr ha scritto una bella risposta sulle pieghe here. Verso la fine è possibile vedere un esempio di sintassi di scelta rapida di foldLeft e foldRight.

14

Personalmente preferisco le forme /: e :\ di foldLeft e foldRight. Due motivi:

  1. Ha una sensazione più naturale perché si può vedere che si stanno spingendo un valore nella sinistra/destra di una collezione e l'applicazione di una funzione. Questo è

    (1 /: ints) { _ + _ } 
    
    ints.foldLeft(1) { _ + _ } 
    

    Sono entrambi equivalenti, ma io tendo a pensare che il primo enfatizza la mia intuizione di ciò che sta accadendo. Se vuoi sapere come come sta accadendo (es.il metodo sembra essere chiamato sul valore 1, non sulla raccolta), perché i metodi che terminano in due punti sono giusti-associativi. Questo può essere visto in ::, +: ecc ecc. Nella libreria standard.

  2. L'ordinamento dei parametri Function2 è lo stesso ordine come l'elemento piegato e ciò che viene piegato in:

    (b /: as) { (bb, a) => f(bb, a) } 
    //^^ ^^
    //^^ ^^
    // B A  B A 
    

    meglio in ogni modo di:

    as.foldLeft(b) { (bb, a) => f(bb, a) } 
    

    Anche se ammetto che questa era una differenza molto più importante nell'era precedente al supporto decente dell'IDE: oggigiorno IDEA può dirmi quale funzione è prevista con un semplice CTRL-P

Spero che dovrebbe anche essere ovvio come :\ funziona con foldRight - è fondamentalmente esattamente la stessa, tranne che il valore sembra essere spinto dal lato destro. Devo dire che tendo a sterzare bene da foldRight in scala a causa di come viene implementato (cioè erroneamente).

+0

Mi hai convinto. Sto passando a /: da ora in poi. –