Какова цель Function.const? - PullRequest
       24

Какова цель Function.const?

17 голосов
/ 08 мая 2011

Это в ScalaDoc , но без особой документации. Кажется, он всегда возвращает первый параметр.

Function.const(1)(2) например возвращает 1.

Почему он существует и почему он полезен?

Ответы [ 2 ]

25 голосов
/ 08 мая 2011

Это полезно для передачи в качестве аргумента функции более высокого порядка. Например, чтобы заменить все элементы списка на один и тот же элемент:

scala> List(1, 2, 3, 4, 5).map(Function.const(7))
res1: List[Int] = List(7, 7, 7, 7, 7)

Можно, конечно, написать

scala> List(1, 2, 3, 4, 5).map(_ => 7)
res2: List[Int] = List(7, 7, 7, 7, 7)

В зависимости от контекста один может быть более читабельным, чем другой.

19 голосов
/ 08 мая 2011

Чтобы дать более теоретический ответ: const является K-комбинатором исчисления SKI . Иногда он появляется, когда вы работаете с довольно абстрактными понятиями, когда вам не над чем работать. Рассмотрим черту Functor (стиль 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] 
}

Теперь fmap должен быть абстрактным, поскольку он является самой сущностью функтора. Но мы можем написать общую реализацию left, и здесь нам нужно 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)
}

Тест с опцией:

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

Как вы можете видеть, левый делает то, что должен (оборачивая значение в некоторый функтор, когда у нас уже есть «образец для подражания» или «шаблон» для этого функтора во втором аргументе). Определить его очень абстрактно, ничего не зная о типе функтора, можно было только с помощью const.

...