Assuming F[_ <: A] <: B as type-level analog of f: A => B, let [F[_ <: Int] <: List[Int], A <: Int], then should't type application F[A] yield List[Int] when A = Int, so f(List(42)) should compile in the following case
$ scala3-repl
scala> def f[F[_ <: Int] <: List[Int], A <: Int](as: F[A]) = as
def f[F[_$1] <: List[Int], A <: Int](as: F[A]): F[A]
scala> f(List(42))
1 |f(List(42))
| ^^^^^^^^
|Found: List[Int]
|Required: F[A]
|
|where: A is a type variable with constraint <: Int
| F is a type variable with constraint <: [_$1 <: Int] =>> List[Int]
Applying the error message by explicitly providing type parameters makes it work
scala> f[[_ <: Int] =>> List[Int], Int](List(42))
val res0: List[Int] = List(42)
Where does the analogy break? Where is my mental model of considering F[_ <: Int] <: List[Int] as a type-level function from Int to List[Int] wrong?
Firstly regarding inferring type lambdas, I think that type inference would not go to the extent of coming up with type lambdas just to satisfy the constraints otherwise intuitively it would seem like everything would essentially be able typecheck with some convoluted type lambda and that would not be useful in picking up type errors.
As to why
f[List, Int](List(42))fails to compile (and thus fails to get inferred) we would need to refer to the Subtyping Rules of type lambdas:Also note that:
Which means all of these will compile:
And all of these will not:
In the case of:
If you view it from the same type lambda perspective
f[[x] =>> List[x], Int](List(42))should work, and thusf[List, Int](List(42))would also compile (and be inferred).