Объявить естественное преобразование для пакетной обработки с помощью kind-projector
У меня есть следующая черта:
trait Test[F[_]]{
def foo: F[Int]
}
И я попытался применить к нему так называемое пакетное преобразование следующим образом:
def withBatching[F[_]](t: Test[F], nat: F ~> F[List[*]]): Test[F[List[*]]] = ???
Проблема в том, что он не компилируется со следующей ошибкой:
[error] /Hello.scala:15:66: F[[α$1$]List[α$1$]] takes no type parameters, expected: 1
[error] def withBatching[F[_]](t: Test[F], nat: F ~> F[List[*]]): Test[F[List[*]]] = ???
[error] ^
[error] /Hello.scala:15:48: F[[α$0$]List[α$0$]] takes no type parameters, expected: 1
[error] def withBatching[F[_]](t: Test[F], nat: F ~> F[List[*]]): Test[F[List[*]]] = ???
Есть ли способ объявить что-то вродеF[List[*]]
с добрым проектором?
UPD: нашел обходной путь с псевдонимами типов.type ListT[F[_], A] = F[List[A]]
который, кажется, работает, но есть ли более естественный способ сделать это?
1 ответ
*
всегда связывает на самом жестком уровне, что не то, что вам нужно дляnat
и тип возвращаемого значения. Вы должны использоватьLambda
синтаксис, предоставленный kind-projector для явного выбора уровня:
def withBatching[F[_]](
t: Test[F], nat: F ~> Lambda[A => F[List[A]]]
): Test[Lambda[A => F[List[A]]]] = ???