Translate

jueves, 19 de septiembre de 2019

Funciones con funciones como parámetros en Scala

En Scala una función puede tomar otra función como parámetro. Veamos un ejemplo:

def valueAtOneQuarter(f: (Double) => Double) = f(0.25)

Como vemos el parámetro puede ser cualquier función que reciba y devuelva un Doble. La función valueAtOneQuarter calcula el valor de esa función en 0.25.
Por ejemplo,

valueAtOneQuarter(ceil _) // 1.0
valueAtOneQuarter(sqrt _) // 0.5 (because 0.5 × 0.5 = 0.25)

¿Cuál es el tipo de valueAtOneQuarter? Es una función con un parámetro, por lo que su tipo se escribe como :

(parameterType) => resultType

El resultType es claramente Double, y el parameterType ya se encuentra en el encabezado de la función como (Double) => Double. Por lo tanto, el tipo de valueAtOneQuarter es :

((Double) => Double) => Double

Como valueAtOneQuarter es una función que recibe una función, se denomina función de orden superior.

Una función de orden superior también puede producir una función, es decir el resultado es una función. Veamos un ejemplo :

def mulBy(factor : Double) = (x : Double) => factor * x

Esta función nos permite obtener otra función que multiplica un número por el factor, veamos un ejemplo de uso :

val quintuple = mulBy(5)
quintuple(20) // 100

La función mulBy tiene un parámetro de tipo Double, y devuelve una función de tipo (Double) => Double. Por lo tanto, su tipo es

(Double) => ((Double) => Double)

Esta es una de las características que me gustan mucho de scala que contamos con funciones de orden superior de tipado estático y nos ayuda la inferencia de tipo.