Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

What is the expected behavior of Tuple.InverseMap in presence of a type alias in Scala 3.4+? #21534

arainko started this conversation in General Discussion
Discussion options

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?

You must be logged in to vote

Replies: 1 comment 2 replies

Comment options

AliasedOption is considered a polymorphic class type, because it is a perfect eta-expansion of Option. AliasedEither is not the eta-expansion of Either.

You must be logged in to vote
2 replies
Comment options

If [A] =>> Either[String, A] works, why not type AliasedEither[A] = Either[String, A] or type AliasedEither2 = [A] =>> Either[String, A]?

Comment options

My (perhaps flawed) understanding is:

  • Firstly that from a practical perspective, the HKTypeLambda is reduced by the typer before we reach the MatchTypeCaseSpec, so there is little difference here between it, and having specialized InverseMap 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).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

AltStyle によって変換されたページ (->オリジナル) /