2012-02-24 12 views
6

Al intentar responder a esta pregunta: Leave off underscore in function literal Intenté codificar un ejemplo y me enfrenté a un comportamiento extraño.Scala: resultado inverso al escapar subrayado con :::

scala> val myList = 1::2::Nil 
myList: List[Int] = List(1, 2) 

scala> def concat:(List[Int]=> List[Int]) = myList::: 
concat: (List[Int]) => List[Int] 

scala> concat(3::Nil) 
res1: List[Int] = List(3, 1, 2) 

Aunque no tengo la buena respuesta cuando uso _ o x=> f(x) sintaxis.

scala> def concat0:(List[Int]=> List[Int]) = x=> myList:::x 
concat0: (List[Int]) => List[Int] 

scala> def concat1:(List[Int]=> List[Int]) = myList::: _ 
concat1: (List[Int]) => List[Int] 

scala> concat0(3::Nil) 
res2: List[Int] = List(1, 2, 3) 

scala> concat1(3::Nil) 
res3: List[Int] = List(1, 2, 3) 

¿Hay una explicación racional por qué se produce después de myList3::Nil en la función concat?

Respuesta

7

myList ::: _ se traduce en _.:::(myList), mientras que myList ::: se traduce en myList.:::(_).

tl; dr

This post entra en más detalles acerca de los métodos asociativos adecuados. ¿Qué está pasando aquí es:

  • def concat0:(List[Int]=> List[Int]) = x=> myList:::x
    • Scala compilador puede inferir que x, si es de tipo List[Int]
    • List tiene un método :::
    • Debido a las reglas de asociatividad por la derecha, esto se convierte en x.:::(myList) , que precede a myList a x.
  • def concat: (Lista [Int] => Lista [Int]) = miLista :::
    • myList, si es de tipo List[Int]
    • No hay lado derecho de :::, por lo que hay no asociatividad a la derecha
    • En su lugar, el compilador infiere a. entre myList y :::
    • myList.::: es el mismo que x => myList.:::(x), que antepone x a myList.
+0

Gracias por la publicación realmente detallada y clara. –