¿Cuál es el propósito de Function.const?
scala field declaration (2)
Está en ScalaDoc pero sin mucha documentación. Parece que siempre devuelve el primer parámetro.
Function.const(1)(2)
por ejemplo, devuelve 1
.
¿Por qué existe y por qué es útil?
Es útil para pasar como argumento a una función de orden superior. Por ejemplo, para reemplazar todos los elementos de una lista con el mismo elemento:
scala> List(1, 2, 3, 4, 5).map(Function.const(7))
res1: List[Int] = List(7, 7, 7, 7, 7)
Por supuesto, también podrías escribir
scala> List(1, 2, 3, 4, 5).map(_ => 7)
res2: List[Int] = List(7, 7, 7, 7, 7)
Dependiendo del contexto, uno puede ser más legible que el otro.
Para dar una respuesta más teórica: const es el combinador K del cálculo de SKI . A veces aparece cuando trabajas con conceptos bastante abstractos en los que no tienes mucho "para trabajar". Considere un rasgo de Functor (estilo Haskell):
trait Functor[F[_]] {
def fmap[A,B](f:A=>B, fa: F[A]):F[B]
//(<$) in Haskell
def left[A,B](a:A, fb:F[B]):F[A]
}
Ahora fmap necesita ser abstracto, ya que es la esencia misma de un funtor. Pero podemos escribir una implementación general de la izquierda, y aquí necesitamos const:
trait Functor[F[_]] {
def fmap[A,B](f:A=>B, fa: F[A]):F[B]
//(<$) in Haskell
def left[A,B](a:A, fb:F[B]):F[A] =
fmap(Function.const(a), fb)
}
Prueba con opción:
case object OptionFunctor extends Functor[Option] {
def fmap[A,B] (f:A=>B, fa:Option[A]):Option[B] = fa match {
case Some(a) => Some(f(a))
case None => None
}
}
//left works:
OptionFunctor.left("test",Some(42))
//--> Option[java.lang.String] = Some(test)
OptionFunctor.left("test",None:Option[Int])
//--> Option[java.lang.String] = None
Como puede ver, la izquierda hace lo que debería (encerrar un valor en algún funtor cuando ya tenemos un "modelo de rol" o "patrón" para este functor en el segundo argumento). Definirlo de manera muy abstracta sin saber nada sobre el tipo de functor solo fue posible usando const.