What's the purpose of Function.const?
It is in ScalaDoc but without much documentation. It seems that it always returns the first parameter.
Function.const(1)(2)
for instance returns 1
.
Why does 开发者_JAVA技巧it exist and why is it useful?
It's useful for passing as an argument to a higher-order function. For example, to replace all elements of a list with the same element:
scala> List(1, 2, 3, 4, 5).map(Function.const(7))
res1: List[Int] = List(7, 7, 7, 7, 7)
You could of course also write
scala> List(1, 2, 3, 4, 5).map(_ => 7)
res2: List[Int] = List(7, 7, 7, 7, 7)
Depending on the context, one might be more readable than the other.
To give a more theoretical answer: const is the K combinator of the SKI calculus. It pops sometimes up when you work with quite abstract concepts where you don't have much "to work with". Consider a (Haskell style) Functor trait:
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]
}
Now fmap needs to be abstract, as it is the very essence of a functor. But we can write a general implementation of left, and here we need 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)
}
Test with Option:
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
As you can see left does what it should (wrapping a value in some functor when we have already a "role model" or "pattern" for this functor in the second argument). Defining it very abstract without knowing anything about the kind of functor was only possible by using const.
精彩评论