I'm trying to write a trait that contains given instances for a tuple type (yes I know that summonAll exists):
trait TupleInstances[C[_], T <: Tuple] {
val instances: Tuple.Map[T, C]
}
given[C[_]]: TupleInstances[C[_], EmptyTuple] with {
val instances = EmptyTuple
}
inline given[C[_], H, T <: Tuple] (using ch: C[H], ti: TupleInstances[C, T]): TupleInstances[C, H *: T] with {
val instances: Tuple.Map[H *: T, C] = ch *: ti.instances
}
and getting the error
val instances: Tuple.Map[H *: T, C] = ch *: ti.instances
| ^^^^^^^^^^^^^^^^^^
| Found: C[H] *: Tuple.Map[T, C]
| Required: Tuple.Map[H *: T, C]
|
| Note: a match type could not be fully reduced:
|
| trying to reduce Tuple.Map[T, C]
| failed since selector T
| does not match case EmptyTuple => EmptyTuple
| and cannot be shown to be disjoint from it either.
| Therefore, reduction cannot advance to the remaining case
|
| case h *: t => C[h] *: scala.Tuple.Map[t, C]
So essentially I need to prove that for all F[_], Tup:
Tuple.Map[Tup, F] =:= (F[Tuple.Head[Tup]] *: Tuple.Map[Tuple.Tail[Tup], F])
How do I go about doing that?
Firstly,
TupleInstances[C[_], EmptyTuple](forC[_]andtrait TupleInstances[C[_], T <: Tuple]) is incorrectCorrect is higher-kinded
TupleInstances[C, EmptyTuple]orTupleInstances[C[*], EmptyTuple](withscalacOptions += "-Ykind-projector") orTupleInstances[[t] =>> C[t], EmptyTuple].TupleInstances[C[_], EmptyTuple]is supposed to mean the same eventually but currently it means existentialTupleInstances[C[?], EmptyTuple].Polymorphic method works with type lambda, but not with type wildcard in Scala 3
Rules for underscore usage in Higher Kinded Type parameters
Secondly,
match types, and
type classes
are two different ways to perform type-level calculations in Scala 3 (like type projections and type classes in Scala 2 or like type families and type classes in Haskell). If you want to mix them, some corner cases are possible.
You can add one more constraint
Or using
summonFromandinlineScala is not an actual theorem prover. It can check that
C[H] *: Tuple.Map[T, C] =:= Tuple.Map[H *: T, C]for specificC,H,Tbut can't for arbitraryHow to define induction on natural numbers in Scala 2.13?
Also you should reconsider whether you'd like to formulate the whole logic in terms of match types rather than type classes
or you'd like to formulate the whole logic in terms of type classes rather than match types
In Scala 3, how to replace General Type Projection that has been dropped?
What does Dotty offer to replace type projections?