Типы с более высоким родом по сравнению с дженериками - PullRequest
0 голосов
/ 11 июня 2018

Я читаю о более высоконадежных типах в Scala и не могу обернуться вокруг использования подчеркивания.

Например:

trait Functor[F[_]] {
  def map[A, B](fa: F[A])(f: A => B) : F[B]
}

val listFunctor = new Functor[List] {
  override def map[A, B](fa: List[A])(f: A => B) = fa.map(f)
}

listFunctor.map(List(1,2,3))(_ + 3)

Если я использую параметризованный тип A в признаке, я получаю тот же результат:

trait Functor2[F[A]] {
  def map[A, B](fa: F[A])(f: A => B) : F[B]
}

val listFunctor2 = new Functor2[List] {
  override def map[A, B](fa: List[A])(f: A => B) = fa.map(f)
}

listFunctor2.map(List(1,2,3))(_ + 3)

Есть ли существенная разница междудва примера?

1 Ответ

0 голосов
/ 11 июня 2018

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

Я обычно предпочитаю использовать синтаксис F[_], поскольку он поясняет, что нам нужен конструктор типаи у нас нет случайного перекрытия в именовании между заполнителем и типами, как указано в классе: в последнем случае, даже если они случаются для ссылки на один и тот же параметр типа, не существует принудительного ограничения междуA в сигнатуре конструктора и A в сигнатуре метода map, и это также может привести к некоторой путанице относительно природы двух A и того, как они связаны друг с другом.

...