function scala parameters const library-design

¿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.