2010-03-01 12 views
11

He visto este uso del ejemplo Function.tupled en otro answer: Map(1 -> "one", 2 -> "two") map Function.tupled(_ -> _.length).Sí. Sintaxis de función y marcador de posición

Funciona:

scala> Map(1 -> "one", 2 -> "two") map Function.tupled(_ -> _.length) 
<console>:5: warning: method tupled in object Function is deprecated: 
Use `f.tuple` instead 
     Map(1 -> "one", 2 -> "two") map Function.tupled(_ -> _.length) 
               ^
res0: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 2 -> 3) 

Parece que puedo prescindir si no quiero usar la sintaxis marcador de posición.

scala> Map(1 -> "one", 2 -> "two") map (x => x._1 -> x._2.length) 
res1: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 2 -> 3) 

El uso directo de la sintaxis marcador de posición no funciona:

scala> Map(1 -> "one", 2 -> "two") map (_._1 -> _._2.length) 
<console>:5: error: wrong number of parameters; expected = 1 
     Map(1 -> "one", 2 -> "two") map (_._1 -> _._2.length) 

¿Cómo funciona Function.tupled? Parece que suceden muchas cosas en Function.tupled(_ -> _.length). ¿También cómo lo usaría para no recibir la advertencia de desaprobación?

+0

@huynhjl La degradación de Function.tupled es el resultado del entendimiento de que una función debe saber cómo voltearse sin ayuda. Sin embargo, eso realmente no funciona bien con la inferencia de tipo. Espero que no eliminen Function.tupled sin hacer que el tipo inferencer sea lo suficientemente inteligente como para evitar este problema. –

+0

No lo preparé por ahora. – extempore

Respuesta

15

ACTUALIZACIÓN La desaparición fue removed hoy, en respuesta a este problema.


Tupling una función es simplemente adaptando FunctionN[A1, A2, ..., AN, R] a un Function1[(A1, A2, ..., AN), R]

Function.tuple está en desuso en favor de FunctionN#tupled. Una (posiblemente no deseado) consecuencia de esto es que el tipo inferencer no puede deducir los tipos de parámetros en:

scala> Map(1 -> "one", 2 -> "two") map (_ -> _.length).tupled     
<console>:5: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$minus$greater(x$2.length)) 
     Map(1 -> "one", 2 -> "two") map (_ -> _.length).tupled 
             ^
<console>:5: error: missing parameter type for expanded function ((x$1: <error>, x$2) => x$1.$minus$greater(x$2.length)) 
     Map(1 -> "one", 2 -> "two") map (_ -> _.length).tupled 

Cualquiera de estos funcionará:

scala> Map(1 -> "one", 2 -> "two") map { case (a, b) => a -> b.length } 
res8: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 2 -> 3) 

scala> Map(1 -> "one", 2 -> "two") map ((_: Int) -> (_: String).length).tupled   
res9: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 2 -> 3) 

scala> Map(1 -> "one", 2 -> "two") map ((p: (Int, String)) => p._1 -> p._2.length) 
res12: scala.collection.immutable.Map[Int,Int] = Map(1 -> 3, 2 -> 3) 

le sugiero que lea las respuestas a esta reciente pregunta para obtener una comprensión más profunda de '_' en los literales de la función, y cómo funciona el tipo de inferencia:

In Scala, what is the difference between using the `_` and using a named identifier?

ACTUALIZACIÓN

Respondiendo al comentario, lo hace.

scala> val f = (x:Int, y:String) => x + ": " + y 
f: (Int, String) => java.lang.String = <function2> 

scala> f.tupled 
res0: ((Int, String)) => java.lang.String = <function1> 

scala> Map(1 -> "1") map f.tupled 
res1: scala.collection.immutable.Iterable[java.lang.String] = List(1: 1) 

Esto requiere Scala 2.8. Tenga en cuenta que Map # map puede dar como resultado otro mapa, si el tipo de retorno de la función es Tuple2, de lo contrario, List, como se indicó anteriormente.

+0

Gracias por la respuesta. Lo que me confunde es que esto no funciona: 'val f = (x: Int, y: String) => x +": "+ y; f.tupled'. ¿No debería eso devolver una versión de f que funcione en una tupla (Int, String)? – huynhjl

+0

bien, ya veo, eso explica mucho. Volví a probar con 2.8.0.Beta1 y funciona como esperaba. Intenté antes con 2.8.0.Beta1-RC5 que tenía en mi camino. Necesito deshacerme de RC5 ... – huynhjl

Cuestiones relacionadas