def rightArgs(law: LT[R, V], r: R, it: Iterable[V]): Boolean = law match
case s: ((R) => Boolean) => s(r)
case s: ((R, V) => Boolean) => it.forall(x => s(r, x))
case s: ((R, V, V) => Boolean) => it.forall(x => it.forall(y => s(r, x, y)))
case s: ((R, V, V, V) => Boolean) => it.forall(x => it.forall(y => it.forall(z => s(r, x, y, z))))
and many others (in the standard library and compiler, too) could be made parametric with a few extra utilities.
Domain and codomain types
Currently, it is hard to process functions because you can only match them direct-style.
Adding the following would make that easier:
trait Function0[+R] ...
type Domain = EmptyTuple
type CoDomain = R
trait Function1[-T1, +R] ...
type Domain = Tuple1[T1]
type CoDomain = R
trait Function2[-T1, -T2, +R] ...
type Domain = Tuple2[T1, T2]
type CoDomain = R
With this feature, you easily use the power of the function Tuple.Map and Tuple.Concat.
Re-assembling or Type-splat
In some cases, you want to take the extracted and processed domains and codomains, and produce a new function type without hard-coding everything.
This can be solved either with a match type taking [Domain, CoDomain] and producing Function[*Domain, CoDomain] or with a type-level splat like the one alluded to with *Domain (expanding a tuple into the required arguments).
Base trait for FunctionN
I was surprised to learn there is no common trait for FunctionN as there is for TupleN (namely Tuple).
Instead, Function is an alias for Function1, which is inconsistent and not very useful.
I propose (for matching and type-safety purposes) that they do get a common trait.
Motivating example
and many others (in the standard library and compiler, too) could be made parametric with a few extra utilities.
Domain and codomain types
Currently, it is hard to process functions because you can only match them direct-style. Adding the following would make that easier:
With this feature, you easily use the power of the function
Tuple.Map
andTuple.Concat
.Re-assembling or Type-splat
In some cases, you want to take the extracted and processed domains and codomains, and produce a new function type without hard-coding everything. This can be solved either with a match type taking
[Domain, CoDomain]
and producingFunction[*Domain, CoDomain]
or with a type-level splat like the one alluded to with*Domain
(expanding a tuple into the required arguments).Base trait for FunctionN
I was surprised to learn there is no common trait for FunctionN as there is for TupleN (namely Tuple). Instead, Function is an alias for Function1, which is inconsistent and not very useful. I propose (for matching and type-safety purposes) that they do get a common trait.
Tupled functions
Right now, the smallest function that has this method is Function2 (https://dotty.epfl.ch/api/scala/Function2.html). I see no reason why this can not be done for Function1 and Function0, removing the special cases I have now (as in https://github.com/lampepfl/dotty/issues/13800).
Result
If everything works out here, a lot of boilerplate around functions could be removed.