-
Notifications
You must be signed in to change notification settings - Fork 1.1k
What is the expected behavior of Tuple.InverseMap
in presence of a type alias in Scala 3.4+?
#21534
-
I've been playing around with use cases of match types after 3.4 and came up with this puzzler:
object Repro { type AliasedOption[A] = Option[A] type AliasedEither[A] = Either[String, A] val eithers = (Right(1), Right(2), Right(3)) val options = (Some(1), Some(2), Some(3)) type InverseMappedOption = Tuple.InverseMap[options.type, Option] // type InverseMappedOption: (Int, Int, Int) type InverMappedAliasedOption = Tuple.InverseMap[options.type, AliasedOption] // type InverMappedAliasedOption: (Int, Int, Int) type InverseMappedEither = Tuple.InverseMap[eithers.type, [A] =>> Either[String, A]] // type InverseMappedEither: (Int, Int, Int) /* The match type contains an illegal case: case io.github.arainko.dht.Repro.AliasedEither[x] *: t => x *: Tuple.InverseMap[t, io.github.arainko.dht.Repro.AliasedEither] (this error can be ignored for now with `-source:3.3`)sbt(191) */ type InverMappedAliasedEither = Tuple.InverseMap[eithers.type, AliasedEither] }
The behavior is the same with -experimental
and import scala.language.experimental.betterMatchTypeExtractors
in scope.
For context - I've ran into this after incorporating a similar pattern in ducktape which is currently on 3.3.3, however it was pointed out to me (here) that the way I intended for it to be used doesn't really work in 3.4+ so I went investigating.
What's the fundamental difference between
type AliasedOption[A] = Option[A]
and
type AliasedEither[A] = Either[String, A]
that makes one of them actually work and the other one don't?
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 1 comment 2 replies
-
AliasedOption
is considered a polymorphic class type, because it is a perfect eta-expansion of Option
. AliasedEither
is not the eta-expansion of Either
.
Beta Was this translation helpful? Give feedback.
All reactions
-
If [A] =>> Either[String, A]
works, why not type AliasedEither[A] = Either[String, A]
or type AliasedEither2 = [A] =>> Either[String, A]
?
Beta Was this translation helpful? Give feedback.
All reactions
-
My (perhaps flawed) understanding is:
- Firstly that from a practical perspective, the
HKTypeLambda
is reduced by the typer before we reach theMatchTypeCaseSpec
, so there is little difference here between it, and having specializedInverseMap
directly. - The perhaps more tricky part is why we could not do the same for the type alias. It would be incorrect to do so in general, because the bounds of type aliases could be narrowed in refinements of the type defining the alias (which as we know, does not play nicely with captures).
Beta Was this translation helpful? Give feedback.