Skip to content

Tuple.Filter doesn't work if the result tuple type is of length more than 1 #10896

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
prolativ opened this issue Dec 23, 2020 · 8 comments
Closed

Comments

@prolativ
Copy link
Contributor

Minimized code

import Tuple.Filter

type IsString[x] = x match {
  case String => true
  case _ => false
}

val x = summon[Filter[(Char, Int), IsString] =:= EmptyTuple]
val y = summon[Filter[("abc", Int), IsString] =:= Tuple1["abc"]]
val z = summon[Filter[("abc", "def"), IsString] =:= Tuple2["abc", "def"]]

Output

val z = summon[Filter[("abc", "def"), IsString] =:= Tuple2["abc", "def"]]
                                                                         ^
Type argument IsString does not conform to upper bound [_$6] =>> Boolean in subpart scala.Tuple.Filter[scala.Tuple$package.EmptyTuple.type, IsString] of inferred type 
  (("abc" : String) *: ("def" : String) *: 
    scala.Tuple.Filter[scala.Tuple$package.EmptyTuple.type, IsString]
  )

Expectation

This should compile and an evidence for type equality should be correctly synthesized

@prolativ
Copy link
Contributor Author

prolativ commented Jan 4, 2021

It looks like the example can be fixed by adding a type bound on the match type

type IsString[x] <: Boolean = x match {
  case String => true
  case _ => false
}

Now the question is: is the fact that the compiler cannot inter the bounds actually a bug or is this an inherent limitation of match types?
Also is there a way to express type bounds when using a type lambda?

One more suspicious thing is that if the bounds are not specified then

val x = summon[Filter[(Char, Int), IsString] =:= EmptyTuple]

does work even though

type Filtered = Filter[(Char, Int), IsString]

itself does not compile

@nicolasstucki
Copy link
Contributor

@OlivierBlanvillain is the match type x match { case String => true; case _ => false } supposed to be a subtype of type true | false?

@nicolasstucki
Copy link
Contributor

Does that mean that the current behavior is correct (i.e. we need the extra <: Boolean)?

@prolativ
Copy link
Contributor Author

The noncompiling snippet was taken from the documentation of Tuple.Filter so if the conclusion is that this behaviour is correct then we should at least update the docs but I'm still wondering whether this used to compile in the past and if so why this couldn't continue to compile

@nicolasstucki
Copy link
Contributor

Indeed, we should update the docs

@mbovel
Copy link
Member

mbovel commented Mar 20, 2023

Documentation seems to have been fixed by 7af9a40.

@mbovel
Copy link
Member

mbovel commented Mar 20, 2023

Does that mean that the current behavior is correct (i.e. we need the extra <: Boolean)?

Seems legit to me. By the current typing rules, match types are not subtypes of the union of their cases.

@mbovel mbovel closed this as completed Mar 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants