I’ll also give my opinion with regards to Qualified Types (a not-even-experimental feature, i.e. take everything with a big grain of salt).
There were two ideas relevant here:
- The name in the predicate does not matter:
(x: Int with x > 0) =:= (y: Int with y > 0)
- We can reuse an identifier already present
So for example we can write:
def posOnly(x: Int with x > 0) = ???
posOnly( 4: (y: Int with y > 0) )
But as you can see, this clashes with the behavior of named tuples:
(a: Int with a > 0) =:= (x: Int with x > 0)
(a: Int, b: Int) !=:= (x: Int, y: Int)
(a: Int with a > 0, b: Int with b > 0) ?=:= (x: Int with x > 0, y: Int with y > 0)
This is not exclusive to qualified types of course, but would be much more widespread than:
(a: Int, b: Int) => a.type =:= (x: Int, y: Int) => x.type
((a: Int, b: Int)) => Int !=:= ((x: Int, y: Int)) => Int
((a: Int, b: Int)) => a.type ?=:= ((x: Int, y: Int)) => x.type