superior orden funciones scala pattern-matching

orden - ¿Hay una forma más limpia de emparejar patrones en las funciones anónimas de Scala?



funciones de orden superior scala (4)

Créalo o no, esto funciona:

val b = List(1, 2) b map({case 1 => "one" case 2 => "two"})

Puede omitir la p => p match en casos simples. Entonces esto debería funcionar:

val c = a map {case ((x,y) -> u) => (y,x) -> u }

Me encuentro escribiendo código como el siguiente:

val b = a map (entry => entry match { case ((x,y), u) => ((y,x), u) } )

Me gustaría escribirlo de otra manera, si solo esto funcionara:

val c = a map (((x,y) -> u) => (y,x) -> u )

¿Hay alguna manera de que pueda obtener algo parecido a esto?


En su ejemplo citado, la solución más limpia es:

val xs = List((1,2)->3,(4,5)->6,(7,8)->9) xs map { case (a,b) => (a.swap, b) }


En su ejemplo, hay tres semánticas sutilmente diferentes a las que puede aspirar.

  1. Mapa sobre la colección, transformando cada elemento que coincida con un patrón. Lanza una excepción si algún elemento no coincide. Esta semántica se logra con

    val b = a map { case ((x, y), u) => ((y, x), u) }

  2. Mapa sobre la colección, transformando cada elemento que coincida con un patrón. Descarte en silencio los elementos que no coinciden:

    val b = a collect { case ((x, y), u) => ((y, x), u) }

  3. Mapa sobre la colección, desestructurando de forma segura y luego transformando cada elemento. Estas son las semánticas que esperaría para una expresión como

    val b = a map (((x, y), u) => ((y, x), u)))

    Desafortunadamente, no existe una sintaxis concisa para lograr esta semántica en Scala. En cambio, debes destructurarte a ti mismo:

    val b = a map { p => ((p._1._2, p._1._1), p._2) }

    Uno podría tener la tentación de usar una definición de valor para la desestructuración:

    val b = a map { p => val ((x,y), u) = p; ((y, x), u) }

    Sin embargo, esta versión no es más segura que la que usa concordancia explícita de patrones . Por esta razón, si desea la semántica de desestructuración segura, la solución más concisa es escribir explícitamente su colección para evitar ampliaciones involuntarias y usar concordancia explícita de patrones:

    val a: List[((Int, Int), Int)] = // ... // ... val b = a map { case ((x, y), u) => ((y, x), u) }

    Si la definición de un usuario aparece lejos de su uso (por ejemplo, en una unidad de compilación separada), puede minimizar el riesgo al atribuir su tipo en la llamada al mapa:

    val b = (a: List[((Int, Int), Int)]) map { case ((x, y), u) => ((y, x), u) }


val b = a map { case ((x,y), u) => ((y,x), u) }