Что такое добрый проектор
Я копался в FP и во всем, что его окружает, и я нашел идею доброго проектора, написанную где-то, без подробностей и объяснений.
Единственное, что я нашел, был этот проект github, и я начинаю думать, имел ли он в виду этот конкретный проект или какую-то общую концепцию в FP?
Итак, что же это за проектор? Почему это полезно? (если возможно, можете ли вы привести примеры, ресурсы и т. д.?)
1 ответ
Это действительно немного неловкое название для конкретного плагина для компилятора Scala, на который вы ссылаетесь. Я не думаю, что это имеет какое-то значение для себя, но это как бы соответствует его цели.
Что делает плагин, так это предоставляет альтернативный синтаксис обычному обходному пути Scala для лямбда-типов, который использует языковую функцию, называемую проекциями типов.
Скажи, что ты хотел реализовать Functor
за Either
, Сейчас, Functor
требует вида * -> *
, в то время как Either
имеет вид * -> * -> *
, Поэтому нам нужно сначала исправить первый аргумент, а затем предоставить реализацию для частично примененного конструктора типов. Единственный способ сделать это в "обычной" Scala - это:
implicit def eitherIsFunctor[A]: Functor[{type λ[X] = Either[A, X]}#λ] = { ... }
где {type λ[X] = Either[A, X]}
является анонимным структурным типом, который только немедленно используется для "проецирования" λ
, тип, который мы на самом деле хотим. В Хаскеле вы могли бы просто сказать
instance Functor (Either a) where ...
где Either
частично применяется (и a
количественно определяется автоматически).
Плагин позволяет заменить проекцию чем-то, что больше похоже на обычное частичное приложение в Scala, а именно Either[A, ?]
вместо едва понятного {type λ[X] = Either[A, X]}#λ
(и, я думаю, он также предоставляет лямбды общего типа, всегда преобразуя их в анонимные типы и проекции).
Scala 3 предоставляет лямбда-выражения собственных типов, которые больше не основаны на проекции типа.
Лямбда типа, например
[X] =>> F[X]
определяет функцию от типов к типам.
Например,
trait Functor[F[_]]
new Functor[Either[String, Int]] {} // error
new Functor[({ type λ[X] = Either[String, X] })#λ] {} // Scala 2 type lambda based on type projection
new Functor[λ[X => Either[String, X]]] {} // kind projector type lambda
new Functor[Either[String, *]] {} // kind projector type lambda
new Functor[[X] =>> Either[String, X]] {} // Scala 3 type lambda
Кроме того, существует предложение SIP: Underscore Syntax for Type Lambdas #5379, такое, что
Functor[Either[String, _]] // equivalent to Functor[[X] =>> Either[String, X]]