Syntactic sugar for generalized type constraints (=:=, <:<)


#1

GTCs, Type and Context bounds have very similar syntax.
But GTCs do not have the same sugar that is available to the bounds.

def f[A, F[_]](implicit ev: F[A]) = ...

can be sugared to

def f[A: F] = ...

and for gtcs:

def f[A, B](implicit ev: B =:= A) = ...

so normally, one can assume that the following is valid

def f[A, B =:= A] = ...

however, it is not.
i assume it is because =:=, <:< and <%< are identifiers rather than operators like <:


#2

On the right-hand side of a type parameter’s : you need a unary type function.

For what it’s worth, Dotty already allows:

def foo[A: [T] => T <:< Int] = // ...

If we ever get underscore syntax type lambdas, we will be able to write:

def foo[A: _ <:< Int] = // ...

#3

Until the language supports this directly you can express it with kind-projector, which is a pretty standard plugin in the FP community. Highly recommended.

@ def foo[A, B: ? =:= A] = 42 
defined function foo

@ foo[Int, String] 
cmd1.sc:1: Cannot prove that String =:= Int.
val res1 = foo[Int,String]
              ^
Compilation Failed

@ foo[Int,Int] 
res1: Int = 42

#4

Thank you both for your solutions,
While it’s definitely not the most ideal syntax (like [A, B =:= A]) it’s certainly close enough