Skip to content

A variable should be best instantiation of pattern type (SI-6680 redux) #1870

Closed
@S11001001

Description

@S11001001

Given

trait Stream[+A] 
case class Unfold[S,+A](s: S, f: S => Option[(A,S)]) extends Stream[A] 

You get this warning, and an associated unsound inferred type, as in SI-6680 “Unsoundness bug in pattern matcher when pattern reveals existentials”:

scala> def unbox[A](s: Stream[A]) = s match {case Unfold(s, f) => (s, f)} 
-- Warning: <console> ----------------------------------------------------------
7 |def unbox[A](s: Stream[A]) = s match {case Unfold(s, f) => (s, f)}
  |                                           ^^^^^^^^^^^^
  |           There is no best instantiation of pattern type Unfold[Any^, A^]
  |           that makes it a subtype of selector type Stream[A].
  |           Non-variant type variable S cannot be uniquely instantiated.
  |           (This would be an error under strict mode)
def unbox[A](s: Stream[A]): [A] => (s: Stream[A])(Any, Any => Option[(A, Any)])

But there is a ‘best’ choice, which is moreover sound, which is to introduce a fresh type variable, as you can write explicitly with type pattern variables.

scala> def unbox[A](s: Stream[A]) = s match {
  case u: Unfold[ts, A] =>
    u.s: ts  // the name chosen in this block
    (u.s, u.f)
} 
def unbox[A](s: Stream[A]): [A] => (s: Stream[A])(Any, _ => Option[(A, Any)])

This is based on 39c27b6.

/cc @pchiusano

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions