Это специальный синтаксис для так называемых лямбда-выражений типов, который добавляется плагином Kind Projector.
Either[A, ?]
это ярлык для
({type L[X] = Either[A, X]})#L
Весь код обесценивается до
import cats.Monad
object EitherMonad {
implicit def instance[A]: Monad[({type L[X] = Either[A, X]})#L] = new Monad[({type L[X] = Either[A, X]})#L] {
def pure[B](b: B): Either[A, B] = Right(b)
def flatMap[B, C](fa: Either[A, B])(f: B => Either[A, C]): Either[A, C] =
fa.right.flatMap(f)
}
}
Лямбда-выражения выглядят пугающе, но по сути это очень простая концепция. У вас есть вещь, которая принимает два параметра типа, например Either[A, B]
. Вы хотите предоставить экземпляр монады для Both, но trait Monad[F[_]]
принимает только один параметр типа. Но в принципе это нормально, поскольку ваш экземпляр монады в любом случае связан только со вторым («правильным») аргументом типа. Лямбда типа - это просто способ "исправить" аргумент первого типа, чтобы у вас была правильная форма.
Если бы вы сделали то же самое на уровне стоимости, вы бы даже не подумали об этом дважды. Вы получили функцию двух аргументов
val f: (Int, Int) => Int = ...
И что-то, чему вы хотите передать f, что принимает только 1 аргумент
def foo(x: Int => Int) = ...
Единственный способ привести вещи в соответствие — это исправить один из аргументов.
foo(x => f(1, x))
И это именно то, что лямбда типа делает на уровне типа.
person
Rüdiger Klaehn
schedule
20.12.2015
?
— допустимый символ, в данном случае он такой же, какA
. - person Matt Ball   schedule 21.12.2015