Skip to content
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

Pattern matching introduces unbounded existential type, losing type information #9879

Closed
scabug opened this issue Aug 5, 2016 · 4 comments
Closed
Labels
Milestone

Comments

@scabug
Copy link

scabug commented Aug 5, 2016

I'm confused by the following compile-time error:

private def safeMax[A](xs: List[A])(implicit ev: Ordering[A]): Option[A] = 
  xs match {
    case ys@(_ :: _) => Some(ys.min)
    case Nil               => None
  }


// Exiting paste mode, now interpreting.

<console>:12: error: No implicit Ordering defined for ?A1.
           case ys@(_ :: _) => Some(ys.min)
                                       ^

I'm not sure if it's a bug, but it seemed suspect to me.

EDIT - I first posted this question on StackOverflow - http://stackoverflow.com/questions/38775071/no-implicit-ordering-defined-on-pattern-matched-list.

@scabug
Copy link
Author

scabug commented Aug 5, 2016

Imported From: https://issues.scala-lang.org/browse/SI-9879?orig=1
Reporter: Kevin Meredith (kevinmeredith)
Affected Versions: 2.11.8
See #1786, #6169, #127, #5195

@scabug
Copy link
Author

scabug commented Aug 8, 2016

@SethTisue said (edited on Aug 9, 2016 5:45:17 AM UTC):
Note that in general we prefer that an "I'm not sure if it's a bug" type report begin life as a mailing list thread or SO question rather than a JIRA ticket (since the number of tickets in the system is already overwhelming). (thanks for adding SO link)

Your code compiles and runs just fine in Scala 2.9. So this seems to be a regression in the new pattern matcher.

In the error message, the question mark in ?A1 indicates that the inferred type of ys is an existential type rather than simply List[A] as you were expecting.

:: is a case class, so this is a constructor pattern. SLS 8.1.6 (Constructor Patterns) says "If the case class is polymorphic, then its type parameters are instantiated so that the instantiation of c conforms to the expected type of the pattern". As far as I can tell, this doesn't fully specify the behavior; there might be multiple types which "conform" and therefore satisfy the spec language. So the door seems to be open for the compiler to introduce an existential type.

But it seems the existential doesn't even have a bound; at least, I would expect compiling with -Xprint:typer to show a bound if there was one, and it doesn't. The absence of a bound seems like a violation of 8.1.6 to me, since without the bound, there's no guarantee that List[?A1] conforms to List[A].

And the missing bound causes the error; I conclude that because e.g. this compiles if and only if the bound is included:

scala> def foo[A : Ordering](xs: List[A]) = { val ys: List[A1] forSome { type A1 <: A } = xs; ys.min }

There are a number of existing tickets involving various combinations of pattern matching, existential, and bounds. Some of these tickets (e.g. #1786, #6169) have complicated histories. So, leaving this for Adriaan and/or Jason to decide whether this a duplicate or not.

@scabug
Copy link
Author

scabug commented Aug 8, 2016

@SethTisue said:
As an aside, I'm baffled that it seems to matter here whether we use match or a val pattern:

scala> def foo[A : Ordering](xs: List[A]) = { val ys @ (_ :: _) = xs; ys.min }
foo: [A](xs: List[A])(implicit evidence$1: Ordering[A])A

scala> def foo[A : Ordering](xs: List[A]) = xs match { case ys @ (_ :: _) => ys.min }
<console>:11: error: No implicit Ordering defined for ?A1.
       def foo[A : Ordering](xs: List[A]) = xs match { case ys @ (_ :: _) => ys.min }
                                                                                ^

Perhaps it's a clue.

@scabug
Copy link
Author

scabug commented Aug 9, 2016

@SethTisue said:
at least vaguely related, hard to tell if underlying cause is same: #127 and #5195

@scabug scabug added the patmat label Apr 7, 2017
@scabug scabug added this to the Backlog milestone Apr 7, 2017
@SethTisue SethTisue modified the milestones: Backlog, 2.13.0 Apr 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants