Протестировано с 2.13, но я полагаю, что это было так с 2.12, и я просто не сталкивался с такой проблемой раньше:
trait Extractor[-X, +Y] {
def optional :X => Option[Y] = apply
def apply(x :X) :Option[Y]
def andThen[Z](extractor :Extractor[Y, Z]) :Extractor[X, Z] = {
val first = optional; val second = extractor.optional
Extractor { x :X => first(x).flatMap(second) }
}
def andThen[Z](req :Y => Z) :Extractor[X, Z] = {
val first = optional
Extractor { x :X => first(x).map(req) }
}
def compose[W](extractor :Extractor[W, X]) :Extractor[W, Y] = extractor andThen this
def compose[W](req :W => X) :Extractor[W, Y] = Extractor(req andThen optional)
}
Scalac имеет жалобу crypti c о реализации первого compose
:
Error:(44, 31) type mismatch;
found : net.noresttherein.oldsql.morsels.Extractor[X,Y]
required: W => ?
def compose[W](extractor :Extractor[W, X]) :Extractor[W, Y] = extractor andThen this
Комментирование варианта andThen
с использованием функции решает проблему. Так же, как и изменение кода на extractor.andThen[Y](this)
(ключевым параметром здесь является явный параметр типа). Я предполагаю, что мой тип SAM каким-то образом повышается до функции, но я не могу догадаться, почему он имеет приоритет над методом. Поскольку я представил здесь два «решения», я ищу не столько обходных путей, сколько понять, что происходит. Впервые за многие годы я не понимаю, что происходит, и хотел бы устранить подобные проблемы в будущем.