Buscar..


Observaciones

Scala hace todo lo posible para tratar los métodos y las funciones como sintácticamente idénticos. Pero bajo el capó, son conceptos distintos.

Un método es un código ejecutable y no tiene representación de valor.

Una función es una instancia de objeto real de tipo Function1 (o un tipo similar de otra aridad). Su código está contenido en su método de apply . Efectivamente, simplemente actúa como un valor que puede transmitirse.

Por cierto, la capacidad de tratar las funciones como valores es exactamente lo que se entiende por un lenguaje que tiene soporte para funciones de orden superior. Las instancias de funciones son el enfoque de Scala para implementar esta característica.

Una función de orden superior real es una función que toma un valor de función como argumento o devuelve un valor de función. Pero en Scala, como todas las operaciones son métodos, es más general pensar en métodos que reciben o devuelven parámetros de función. Entonces, el map , tal como se define en Seq podría considerarse como una "función de orden superior" debido a que su parámetro es una función, pero no es literalmente una función; es un metodo

Usando métodos como valores de función

El compilador Scala convertirá automáticamente los métodos en valores de función con el fin de pasarlos a funciones de orden superior.

object MyObject {
  def mapMethod(input: Int): String = {
    int.toString
  }
}

Seq(1, 2, 3).map(MyObject.mapMethod) // Seq("1", "2", "3")

En el ejemplo anterior, MyObject.mapMethod no es una llamada de función, sino que se pasa a map como un valor. De hecho, el map requiere que se le pase un valor de función, como se puede ver en su firma. La firma para el map de una List[A] (una lista de objetos de tipo A ) es:

def map[B](f: (A) ⇒ B): List[B]

La parte f: (A) => B indica que el parámetro para esta llamada de método es alguna función que toma un objeto de tipo A y devuelve un objeto de tipo B A y B se definen arbitrariamente. Volviendo al primer ejemplo, podemos ver que mapMethod toma un Int (que corresponde a A ) y devuelve una String (que corresponde a B ). Por mapMethod tanto, mapMethod es un valor de función válido para pasar al map . Podríamos reescribir el mismo código así:

Seq(1, 2, 3).map(x:Int => int.toString)

Esto incluye el valor de la función, que puede agregar claridad a las funciones simples.

Funciones de alto orden (función como parámetro)

Una función de orden superior, a diferencia de una función de primer orden, puede tener una de tres formas:

  • Uno o más de sus parámetros es una función y devuelve algún valor.

  • Devuelve una función, pero ninguno de sus parámetros es una función.

  • Ambos de los anteriores: uno o más de sus parámetros es una función, y devuelve una función.

    object HOF {
        def main(args: Array[String]) {
        val list = List(("Srini","E"),("Subash","R"),("Ranjith","RK"),("Vicky","s"),("Sudhar","s"))
        //HOF
         val fullNameList= list.map(n => getFullName(n._1, n._2))
    
         }
    
        def getFullName(firstName: String, lastName: String): String = firstName + "." + lastName
        }
    

Aquí la función de mapa toma una función getFullName(n._1,n._2) como parámetro. Esto se llama HOF (función de orden superior).

Argumentos perezosos de evaluación

Scala admite la evaluación perezosa para argumentos de funciones usando notación: def func(arg: => String) . Dicho argumento de función podría tomar un objeto String normal o una función de orden superior con String tipo de retorno String . En el segundo caso, el argumento de la función sería evaluado en el acceso al valor.

Por favor vea el ejemplo:

def calculateData: String = {
  print("Calculating expensive data! ")
  "some expensive data"
}

def dumbMediator(preconditions: Boolean, data: String): Option[String] = {
  print("Applying mediator")
  preconditions match {
    case true => Some(data)
    case false => None
  }
}

def smartMediator(preconditions: Boolean, data: => String): Option[String] = {
  print("Applying mediator")
  preconditions match {
    case true => Some(data)
    case false => None
  }
}

smartMediator(preconditions = false, calculateData)

dumbMediator(preconditions = false, calculateData)

smartMediator llamada a smartMediator devolverá el valor Ninguno e imprimirá el mensaje "Applying mediator" .

dumbMediator llamada a dumbMediator devolverá el valor Ninguno e imprimirá el mensaje "Calculating expensive data! Applying mediator" .

La evaluación perezosa puede ser extremadamente útil cuando desea optimizar una sobrecarga de cálculo de argumentos caros.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow