Let's first address the most complicated type constructor here:
({type l[a]=Either[_, a]})#l
is the original way to encode type lambdas. It could be written more succinctly as either
Either[_, ?]
with kind-projector, or as
[X] =>> Either[_, X]
in Scala 3. It basically just selects the right parameter of Either as the relevant one, and replaces the left parameter by a wildcard.
Now, the three type parameters of OptionLikeMatcher are:
F[_] - the type constructor for the thing that's being matched; It is expected to behave "somewhat similarly" to Option, i.e. there should be some way to get an Option out of it.
T is the type that is plugged into the F type constructor; Together F[T] gives the type of what's being matched.
U can be thought as a "slightly perturbed" version of T; It captures basically the same information as T, but it allows for some controlled sloppiness when transforming an F[T] into an Option[U] (otherwise, if one required F[T] => Option[T], that would practically be the same as asking for quite a rigid structure called natural transformation F ~> Option, which might be too restrictive in this case).
Putting it all together gives for RightMatcher:
F[A] = Either[_, A] - i.e. pick right parameter of Either, ignore left parameter
- The
T from the OptionLikeMatcher is bound to T from RightMatcher
- The
U from the OptionLikeMatcher is also bound to T from RightMatcher, i.e. the possibility to "slightly perturb" T is not used here, both T and U from OptionLikeMatcher are instantiated by the same type.
Thus, the toOption in RightMatcher has the type Either[_, T] => Option[T]. The (_:Either[Any, T]).right.toOption conforms to Either[_, T] => Option[T], because the Any appears in a covariant position within Either, and Either[Any, T] appears in a contravariant position within the function type, so that Either[Any, T] => Option[T] is a subtype of Either[_, T] => Option[T], because its input type is strictly more permissive, and it can be used everywhere an Either[_, T] => Option[T] is needed.
All that being said, I couldn't find any applications of F that were not of shape F[T] (neither in OptionLikeMatcher, nor in OptionLikeChekedMatcher), so it seems that they are splitting up the input type into a type constructor F and a type parameter T, only to use them as an indivisible unit F[T] later on. Maybe this was left over after a refactoring from some more complicated construct.