Можно ли "карри" более высокопородных типов в Scala?
Предположим, у меня есть черта с двумя параметрами типа, например
trait Qux[A, B]
и другой признак с параметром типа с более высоким родом, например
trait Turkle[C[_]]
Я хотел бы иметь возможность заменить фиксированное значение для одного из параметров типа для Qux
, так что это может быть использовано для параметризации Turkle
,
Вот пример (кода, который не имеет смысла в Scala!):
trait Baz[A] extends Turkle[Qux[A, _]]
У кого-нибудь есть идеи, как этого добиться?
4 ответа
Джейсон Заугг придумал самый лаконичный способ сделать это:
trait Baz[A] extends Turkle[({type x[a]=Qux[A, a]})#x]
Плагин IntelliJ Scala при желании свернет это так:
trait Baz[A] extends Turkle[x[a]=Qux[A, a]]
Вы имеете в виду что-то вроде этого?
trait QuxWithString[A] extends Qux[A, String]
new Turkle[QuxWithString]{}
Это аналог частичного применения для типов.
trait Turkle[C[_]]
trait Qux[A,B]
trait Wraps[A] {
type Jkz[X] = Qux[A,X]
trait Baz extends Turkle[Jkz]
}
Проектор плагина компилятора также позволяет:
// Explicit lambda, greek letters
trait Baz[A] extends Turkle[λ[α=>Qux[A,α]]]
// Explicit lambda, normal letters
trait Baz[A] extends Turkle[Lambda[a=>Qux[A,a]]]
// No explicit lambda, ? placeholder
trait Baz[A] extends Turkle[Qux[A,?]]
Scala 3 предлагает SIP: синтаксис подчеркивания для лямбда-выражений типа #5379, так что возможно следующее
trait Baz[A] extends Turkle[Qux[A, _]]
В настоящее время Dotty 0.23.0-RC1 изначально предоставляет лямбды типов с использованием[X] =>> F[X]
синтаксис так попробуйте
trait Baz[A] extends Turkle[[B] =>> Qux[A, B]]