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

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 `<:`

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] = // ...
``````
5 Likes

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 Likes

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