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

Nothing does not conform to arbitrary type parameter #9453

Open
scabug opened this issue Aug 31, 2015 · 5 comments
Open

Nothing does not conform to arbitrary type parameter #9453

scabug opened this issue Aug 31, 2015 · 5 comments
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) infer typelevel
Milestone

Comments

@scabug
Copy link

scabug commented Aug 31, 2015

trait Stuff[A]
def take[A](st: Stuff[A]): Stuff[A] = st

take(??? : Stuff[Nothing])

Result:

<console>:13: error: type mismatch;
 found   : Stuff[Nothing]
 required: Stuff[A]
Note: Nothing <: A, but trait Stuff is invariant in type A.
You may wish to define A as +A instead. (SLS 4.5)
       take(??? : Stuff[Nothing])
                ^

The error goes away if either:

  • type parameter is explicit (i.e. take[Nothing](??? : Stuff[Nothing]))
  • A is covariant
  • A occurs in covariant position in return type of take or does not occur at all

Original SO question: http://stackoverflow.com/questions/32097291/bizzare-type-inference-limitation-multiple-type-params

@scabug
Copy link
Author

scabug commented Aug 31, 2015

Imported From: https://issues.scala-lang.org/browse/SI-9453?orig=1
Reporter: @ghik
Affected Versions: 2.11.7

@scabug
Copy link
Author

scabug commented Aug 31, 2015

@retronym said:
This is a known limitation with type inference: you have to specify the type argument of Nothing explicitly in this case, as the typer retracts the solutions to the local type inference problem that instantiated type variables to Nothing. I'll leave this bug open as I'm not sure if another one directly touches on this problem, but I don't think we'll be able to make this example work without major surgery to inference.

@scabug
Copy link
Author

scabug commented Sep 1, 2015

@milessabin said (edited on Sep 1, 2015 3:02:26 PM UTC):
As an aside, it's possible to synthesize a type equivalent to Nothing which won't cause the typer to retract the solution,

type ReallyNothing = Nothing { type T = Unit }

ie. Nothing with a dummy refinement. Repl session ...

scala> :paste
// Entering paste mode (ctrl-D to finish)

trait Stuff[A]
def take[A](st: Stuff[A]): Stuff[A] = st
 
take(??? : Stuff[ReallyNothing])

// Exiting paste mode, now interpreting.

scala.NotImplementedError: an implementation is missing
  at scala.Predef$.$qmark$qmark$qmark(Predef.scala:225)
  ... 37 elided

@scabug
Copy link
Author

scabug commented Oct 13, 2015

@pchiusano said (edited on Oct 13, 2015 8:26:37 PM UTC):
I have hit this issue also, though my situation is a bit different so I thought I'd add a bit more.

I have a trait Stream[+F[_],+O], where a Stream[Nothing,A] represents a pure stream which uses no effects, and a Stream[F,A] may request evaluation of F[_] effects in between emitting values to the output. The advantage of using Nothing to represent pure streams is that normal subtyping will promote that to whatever F[_] the context requires, no need for explicit lifting.

The problem is when calling a function like this one:

def pull[F[_],A,B](s: Stream[F,A])(using: Handle[F,A] => Pull[F,B,Any]): Stream[F,B]

in conjunction with a polymorphic function like

def take[F[_],I]: Handle[F,I] => Pull[F,I,Handle[F,I]]

The issue is that Scala won't infer Nothing for the argument to take or the pull type parameter, which leads to needing to write:

val purePull = Stream.pull[Nothing,Int,Int](Stream(1,2,3,4))(process1.take[Nothing,Int](2))

Both those annotations are needed. Not very good. :(

What stops me from directly using the dummy refinement trick Miles mentions above is that I am relying on the fact that Nothing is polykinded, but for any type alias one must pick a single kind for it.

@joroKr21
Copy link
Member

This bug is on the second to last page 😄 #1570

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) infer typelevel
Projects
None yet
Development

No branches or pull requests

5 participants