dotty-feature-requests
dotty-feature-requests copied to clipboard
Tuple.IsMappedBy should provide inductive instances
minimized code
def isMappedByShouldBeInductive1[F[_], A, B <: Tuple](using ev: Tuple.IsMappedBy[F][A *: B]) =
summon[Tuple.IsMappedBy[F][B]]
def isMappedByShouldBeInductive2[F[_], A <: Tuple](using ev: Tuple.IsMappedBy[F][A]) =
summon[Tuple.IsMappedBy[F][Tuple.Tail[A]]]
Compilation output
scala> def isMappedByShouldBeInductive1[F[_], A, B <: Tuple](using ev: Tuple.IsMappedBy[F][A *: B]) = summon[Tuple.IsMappedBy[F][B]]
1 |def isMappedByShouldBeInductive1[F[_], A, B <: Tuple](using ev: Tuple.IsMappedBy[F][A *: B]) = summon[Tuple.IsMappedBy[F][B]]
| ^
|no implicit argument of type Tuple.IsMappedBy[F][B] was found for parameter x of method summon in object DottyPredef.
|I found:
|
| <:<.refl[Nothing]
|
|But method refl in object <:< does not match type Tuple.IsMappedBy[F][B].
scala> def isMappedByShouldBeInductive2[F[_], A <: Tuple](using ev: Tuple.IsMappedBy[F][A]) = summon[Tuple.IsMappedBy[F][Tuple.Tail[A]]]
1 |def isMappedByShouldBeInductive2[F[_], A <: Tuple](using ev: Tuple.IsMappedBy[F][A]) = summon[Tuple.IsMappedBy[F][Tuple.Tail[A]]]
| ^
|no implicit argument of type Tuple.IsMappedBy[F][Tuple.Tail[A]] was found for parameter x of method summon in object DottyPredef.
|I found:
|
| <:<.refl[Nothing]
|
|But method refl in object <:< does not match type Tuple.IsMappedBy[F][Tuple.Tail[A]].
Workaround
given a[F[_], Head, Tail <: Tuple](using Tuple.IsMappedBy[F][Head *: Tail]) as Tuple.IsMappedBy[F][Tail] = Predef.$conforms.asInstanceOf
given b[F[_], T <: NonEmptyTuple](using Tuple.IsMappedBy[F][T]) as Tuple.IsMappedBy[F][Tuple.Tail[T]] = Predef.$conforms.asInstanceOf
def isMappedByShouldBeInductive1[F[_], A, B <: Tuple](using ev: Tuple.IsMappedBy[F][A *: B]) =
summon[Tuple.IsMappedBy[F][B]]
def isMappedByShouldBeInductive2[F[_], A <: NonEmptyTuple](using ev: Tuple.IsMappedBy[F][A]) =
summon[Tuple.IsMappedBy[F][Tuple.Tail[A]]]
Conversly
given c[F[_], Elem, T <: Tuple](using Tuple.IsMappedBy[F][T]) as Tuple.IsMappedBy[F][F[Elem] *: T] = Predef.$conforms.asInstanceOf
b works for both cases but does not get infered in the first case
def isMappedByShouldBeInductive1[F[_], A, B <: Tuple](using ev: Tuple.IsMappedBy[F][A *: B]) =
summon[Tuple.IsMappedBy[F][B]]//(using b)
given b[F[_], T <: NonEmptyTuple](using Tuple.IsMappedBy[F][T]) as Tuple.IsMappedBy[F][Tuple.Tail[T]] = Predef.$conforms.asInstanceOf
In case it's interesting, I was using this in scodec to implement Codec.fromTuple -- I ended up casting instead of relying on the inductive instances.
https://github.com/scodec/scodec/blob/50ca6194d8bbb571b7ba956cbe3c19ae242b0128/shared/src/main/scala/scodec/Codec.scala#L628-L637