Supongamos que tengo una clase de caso simple que envuelve enteros, y un método de orden superior que acepta una función que transporta enteros a envoltorios.¿Por qué reemplazar mi clase de caja Scala con un extractor rompió mi función de orden superior?
case class Wrapper(x :Int)
def higherOrder(f : Int => Wrapper) = println(f(42))
Luego, puedo llamar a la función de orden superior, pasando la función de aplicación generada del contenedor. Sorprendentemente, también puedo pasar el nombre del envoltorio.
higherOrder(Wrapper.apply) // okay
higherOrder(Wrapper) // okay, wow!
Esto es realmente genial. Nos permite tratar el nombre de la clase de caso como una función, que fomenta abstracciones expresivas. Para ver un ejemplo de esta frialdad, mira la respuesta aquí. What does "abstract over" mean?
Supongamos que mi clase de caso no es lo suficientemente potente, y necesito crear un extractor en su lugar. Como un caso de uso levemente artificial, digamos que necesito poder hacer coincidir patrones en cadenas que se convierten en enteros.
// Replace Wrapper case class with an extractor
object Wrapper {
def apply(x :Int) = new Wrapper(x)
def unapply(s :String) :Option[Wrapper] = {
// details elided
}
}
class Wrapper(x :Int) {
override def toString = "Wrapper(" + x + ")"
// other methods elided
}
Bajo este cambio, todavía puedo pasar Wrapper.apply en mi función de orden superior, pero al pasar en tan sólo Envoltura ya no funciona.
higherOrder(Wrapper.apply) // still okay
higherOrder(Wrapper) // DOES NOT COMPILE
^^^^^^^
// type mismatch; found : Wrapper.type (with underlying type Wrapper)
// required: (Int) => Wrapper
Ouch! He aquí por qué esta asimetría es preocupante. El consejo de Odersky, Spoon y Venners (Programación en Scala, página 500), dice
Siempre puede comenzar con las clases de casos y luego, si es necesario, cambiar a los extractores. Debido a que los patrones sobre los extractores y los patrones sobre las clases de casos se ven exactamente iguales en Scala, las coincidencias de patrones en sus clientes continuarán funcionando.
Muy cierto, por supuesto, pero romperemos a nuestros clientes si están utilizando nombres de clases de casos como funciones. Y como hacerlo permite abstracciones poderosas, algunos seguramente lo harán.
Por lo tanto, al pasarlos a funciones de orden superior, ¿cómo podemos hacer que los extractores se comporten de la misma manera que las clases de casos?
Por favor, no se sienta avergonzado de aceptar una respuesta para cualquiera de sus preguntas. Realmente es muy aceptable socialmente, y casi todos lo han hecho en algún momento. –