2011-09-07 9 views
15

Puede alguien dar algunos ejemplos de cómosintaxis veces Scala vectorial (/: y: /y: )

/::\ and /:\

En realidad se acostumbran? Supongo que son accesos directos a los métodos reducir/doblar, pero no hay ejemplos de cómo se usan realmente en los documentos de Scala, y son imposibles de buscar/buscar en Google en StackOverflow.

+0

También conocido como doblar a la izquierda (pliegue), doblar a la derecha (pliegue) y doblar cualquiera (??). Wikipedia tiene información general e imágenes bonitas sobre [fold hofs] (http://en.wikipedia.org/wiki/Fold_%28higher-order_function%29). –

Respuesta

10

/: es un sinónimo de foldLeft y :\ para foldRight.

Pero recuerde que : hace /: aplicar al objeto a la derecha de la misma.

Suponiendo que saben que (_ * _) es una función anónima que es equivalente a (a, b) => a * b, y la firma de foldLeft y foldRight son

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

es decir, que son funciones al curry que tienen un valor de inicio y una función de la combinación del valor de inicio/acumulador con un elemento de la lista, algunos ejemplos son:

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

que es el mismo que

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

Y

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

en notación infija es

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

que es el mismo que

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

Añada sus propias colecciones y funciones y disfrutar!

Lo que hay que recordar a los cortos (/: y :\) notaciones es que, debido a que está utilizando las notaciones infijos que necesita para poner paréntesis alrededor de la primera parte con el fin de que para recoger la segunda lista de argumentos correctamente. Además, recuerde que las funciones para foldLeft y foldRight son al revés, pero tiene sentido si está visualizando el pliegue en su cabeza.

+0

Olvidé decirlo, '/: \' es un sinónimo de 'fold', que es para doblar cuando no te importa el orden. La sintaxis es como para ': \'. Nunca lo he usado, pero creo que es útil para colecciones paralelas, por lo que puedes dividir una operación de plegado entre varios hilos/actores. –

3

Rex Kerr ha escrito una respuesta agradable sobre pliegues here. Cerca del final, puede ver un ejemplo de sintaxis de acceso directo de foldLeft y foldRight.

14

Personalmente prefiero las formas /: y :\ de y foldRight. Dos razones:

  1. Tiene una sensación más natural, porque se puede ver que usted está empujando un valor en la izquierda/derecha de una colección y aplicación de una función. Eso es

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

    Ambos son equivalentes, pero tiendo a pensar que el primero enfatiza mi intuición en cuanto a lo que está sucediendo. Si desea saber cómo está sucediendo esto, es decir, (es decir,el método parece ser llamado en el valor 1, no en la colección), es porque los métodos que terminan en dos puntos son correlativos a la derecha. Esto se puede ver en ::, +:, etc. en otra parte de la biblioteca estándar.

  2. El orden de los parámetros Function2 es del mismo orden que el elemento de plegado y la que se dobla en:

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

    mejor en todos los sentidos que:

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

    Aunque admito que esta era una diferencia mucho más importante en la era anterior al soporte IDE decente: hoy en día IDEA puede decirme qué función se espera con un simple CTRL-P

Espero que también sea obvio cómo funciona :\ con foldRight; básicamente es exactamente lo mismo, excepto que el valor parece estar siendo insertado desde el lado derecho. Debo decir que tiendo a alejarme bien de foldRight en scala debido a cómo se implementa (es decir, erróneamente).

+0

Me convenciste. Cambiaré a /: a partir de ahora. –