È una sintassi speciale per il cosiddetto tipo lambda che viene aggiunto dallo kind projector plugin.
Either[A, ?]
è una scorciatoia per
({type L[X] = Either[A, X]})#L
L'intero codice desugars per
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)
}
}
tipo lambda aspetto spaventoso, ma sono essenzialmente un concetto molto semplice. Hai una cosa che prende due parametri di tipo, come Either[A, B]
. Si desidera fornire un'istanza monad per Either, ma lo standard trait Monad[F[_]]
richiede un solo parametro di tipo. Ma in linea di principio va bene, dal momento che la tua istanza monad riguarda solo il secondo (il "giusto") argomento di tipo comunque. Un tipo lambda è solo un modo per "sistemare" il primo argomento di tipo in modo da avere la forma giusta.
Se si farebbe la stessa cosa a livello di valore, non ci si potrebbe nemmeno pensare due volte. Hai una funzione di due argomenti
val f: (Int, Int) => Int = ...
E qualcosa che si desidera passare f a, che richiede solo 1 argomento
def foo(x: Int => Int) = ...
L'unico modo per fare le cose in forma è di fissare uno degli argomenti
foo(x => f(1, x))
E questo è esattamente ciò che fa un tipo lambda a livello di tipo.
fonte
2015-12-20 21:42:21
'?' È un simbolo valido, è proprio come 'A' in questo caso. –