Как определить контекст, связанный с типом более высокого типа (конструктор типов)

Я пробовал следующее

def test[Option[T]: Ordering](value1: Option[T], value2: Option[T]) = {
  val e = implicitly(Ordering[Option[T]].compare(value1, value2))
}

а не работает? Есть идеи, в чем проблема?

ИЗМЕНИТЬ

Это конечно работает

def test[T](value1: Option[T], value2: Option[T]) (implicit ev: Ordering[Option[T]]) = {
  ev.compare(value1, value2)
}

person MaatDeamon    schedule 16.09.2020    source источник


Ответы (2)


Если вы действительно настаиваете на использовании привязки к контексту, вы можете написать лямбда-тип:

def test[T: ({type L[x] = Ordering[Option[x]]})#L](value1: Option[T], value2: Option[T]) = {
  val e = implicitly(Ordering[Option[T]].compare(value1, value2))
}

Или с плагином kind-projector вы сможете сделать это немного чище:

def test[T: Lambda[x => Ordering[Option[x]]]](value1: Option[T], value2: Option[T]) = {
  val e = implicitly(Ordering[Option[T]].compare(value1, value2))
}
person Jasper-M    schedule 16.09.2020
comment
Хорошо, я вернусь к исследованию типа лямбда. Спасибо - person MaatDeamon; 16.09.2020

Когда вы пишете def test[Option[T]: Ordering]..., Option не относится к scala.Option, это параметр нового типа (вы можете обозначить его как Option или F как угодно). Так

def test[Option[T]: Ordering](value1: Option[T], value2: Option[T]) = {
  val e = implicitly(Ordering[Option[T]].compare(value1, value2))
}

на самом деле

def test[F[_]: Ordering](value1: F[T], value2: F[T]) = {
  val e = implicitly(Ordering[F[T]].compare(value1, value2))
}

он же

def test[F[_]](value1: F[T], value2: F[T])(implicit ev: Ordering[F]) = {
  val e = implicitly(Ordering[F[T]].compare(value1, value2))
}

Это не компилируется, потому что T не определено, а Ordering[F] не имеет смысла. Что бы скомпилировать

def test[F[_], T](value1: F[T], value2: F[T])(implicit ev: Ordering[F[T]]) = {
  val e = implicitly(Ordering[F[T]].compare(value1, value2))
}

Я бы рекомендовал включить scalacOptions += "-Xlint:type-parameter-shadow".

person Dmytro Mitin    schedule 16.09.2020