Skip to content

Type inference on type lambdas w.r.t tuples is confusing #3075

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
raymondtay opened this issue Sep 6, 2017 · 1 comment
Closed

Type inference on type lambdas w.r.t tuples is confusing #3075

raymondtay opened this issue Sep 6, 2017 · 1 comment

Comments

@raymondtay
Copy link
Contributor

I was reading over dotty's new type lambda syntax and exploring its feature when i came across an observation when i declared the following expressions in dotty's REPL (Using Dotty 0.3-RC1):

scala> type T = [X, _] => (X,X)
scala> val t : T[Int, _] = (1,2)
val t : Int, Int = (1,2) // the wildcard "inherited the 'Int' type"

I guess my question is whether this is legal because in Scala, it seems to interpret to Nothing.

Another example is the following using dotty's REPL

scala> type T = [X, _ , _] => (X, X)
scala> val t: T[Int, _, _] = (1,2)
val t : Int, Int = (1,2) // the 3rd wildcard is gone !

Last example w.r.t type lambdas in tuples is what seems like the usual arithmetic promotion rules in Java/Scala:

scala> type T = [X,_, _] => (X,X)
defined type alias T
scala> val t : T[Float,_ ,_] = (1f, 333)
val t: Float, Float = (1.0,333.0) 
//
// Here's the weird part
//
scala> val a : (Float, _) = (1f, 222)
val a: Float, _ = (1.0,222)
scala> a._2
val res2: a.T2 = 222 // <---- a.T2 is a type that has not been resolved? Was expecting it to be 'Any'
scala> val b : (Float, Float) = {val a : (Float, _) = (1f, 222); (a._1, a._2)}
-- [E007] Type Mismatch Error: <console>:5:67 ----------------------------------
5 |val b : (Float, Float) = {val a : (Float, _) = (1f, 222); (a._1, a._2)}
  |                                                                 ^^^^
  |                                                           found:    a.T2
  |                                                           required: Float
  |
scala> val b : (Float, Any) = {val a : (Float, _) = (1f, 222); (a._1, a._2)} // this WORKS !
val b: Float, Any = (1.0,222)
@smarter
Copy link
Member

smarter commented Sep 6, 2017

val t : Int, Int = (1,2) // the wildcard "inherited the 'Int' type"

I think you're confused, what happened here is that T[Int, _] was replaced by its definition (Int, Int) (the fact that the repl prints val t: Int, Int instead of val t: (Int, Int) is a bug that does not occur anymore on master). The wildcard never "inherited" anything.

scala> val a : (Float, _) = (1f, 222)
val a: Float, _ = (1.0,222)
a._2
val res2: a.T2 = 222 // <---- a.T2 is a type that has not been resolved? Was expecting it to be 'Any'

No, it's a path-dependent type, but it doesn't really make sense here because the type parameter T2 of Tuple is not publically accessible. Using the in-progress #3033 we get val res2: Any = 222 as expected.

@smarter smarter closed this as completed Sep 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants