java - why is specified equivalence between wildcard and existential types not observed in REPL -
according the java programming language 4th ed. section 15.7.1 "type tokens":
getclass receives special treatment compiler: if getclass invoked on reference static type t, compiler treats return type of getclass being class. works:
string str = "hello"; class<? extends string> c2 = str.getclass(); // compiler magic
the javadocs getclass
method in class object
give more detail:
the actual result type [of
getclass()
]class<? extends |x|>
|x|
erasure of static type of expression on getclass called. example, no cast required in code fragment:number n = 0; class<? extends number> c = n.getclass();
that's java , getclass()
method of class object
. switching attention scala, sls 3.2.10 reads,
placeholder syntax existential types
syntax:
wildcardtype ::= ‘_’ typebounds
scala supports placeholder syntax existential types. wildcard type of form _ >: l <: u...a wildcard type shorthand existentially quantified type variable, existential quantification implicit.
...let t = p.c[targs, t, targs'] parameterized type targs, targs' may empty , t wildcard type _ >: l <: u . t equivalent existential type
p.c[targs, t , targs ] forsome { type t >: l <: u }
where t fresh type variable.
i emphasized "t equivalent existential type..." above because behavior observing seems inconsistent statement.
what did
in scala repl try wildcard syntax of sls 3.2.10:
scala> val c: class[_ >: scala.nothing <: string] = "foo".getclass c: class[_ <: string] = class java.lang.string
that works expect. if rely on equivalence claimed in sls 3.2.10 "a wildcard type shorthand existentially quantified type variable," unexpected failure.
scala> val c: class[t forsome { type t >: scala.nothing <: string }] = "foo".getclass <console>:7: error: type mismatch; found : java.lang.class[?0] type ?0 <: java.lang.string required: class[t forsome { type t <: string }] note: ?0 <: t forsome { type t <: string }, java-defined class class invariant in type t. may wish investigate wildcard type such `_ <: t forsome { type t <: string }`. (sls 3.2.10) val c: class[t forsome { type t >: scala.nothing <: string }] = "foo".getclass ^
the error message appears guiding me recursively sls 3.2.10, suggesting use both wildcard syntax along express existential quantification. don't understand means. in event, observe same dichotomy using example object
javadocs quoted above:
scala> val n: number = 0 n: java.lang.number = 0
works:
scala> val c: class[_ >: scala.nothing <: number] = n.getclass c: class[_ <: java.lang.number] = class java.lang.integer
not works:
scala> val c: class[t forsome { type t >: scala.nothing <: number }] = n.getclass <console>:8: error: type mismatch; found : java.lang.class[?0] type ?0 <: java.lang.number required: class[t forsome { type t <: java.lang.number }] note: ?0 <: t forsome { type t <: java.lang.number }, java-defined class class invariant in type t. may wish investigate wildcard type such `_ <: t forsome { type t <: java.lang.number }`. (sls 3.2.10) val c: class[t forsome { type t >: scala.nothing <: number }] = n.getclass
the questions
primarily
if particular wildcard type "equivalent" particular existential type, mean 1 can substituted other? not meaning of equivalence? assuming correctly understanding meaning "equivalence" used in sls 3.2.10, there error in attempt make equivalent substitution according rules set forth in sls 3.2.10? how failures of repl process 2 statements quoted above containing existential types consistent sls 3.2.10, according failing statements equivalent statements using wildcard types succeed?
additionally
what difference between types specified in required , found lines of error messages in question? namely, how this:
java.lang.class[?0] type ?0 <: java.lang.string
different from
class[t forsome { type t <: string }]
and question mark in first one? ?0
means something, seems type variable, using question mark not scala, it? language , specified can understand error message?
look again @ part of spec quoted:
let t = p.c[targs, t, targs'] parameterized type targs, targs' may empty , t wildcard type _ >: l <: u . t equivalent existential type p.c[targs, t , targs ] forsome { type t >: l <: u } t fresh type variable.
in particular, notice says p.c[targs, t , targs ] forsome { type t >: l <: u }
, not p.c[targs, t forsome { type t >: l <: u } , targs ]
. 2 types different.
going context of class
means class[_ >: scala.nothing <: string]
equivalent class[t] forsome { type t >: scala.nothing <: string}
, , not class[t forsome { type t >: scala.nothing <: string }]
.
and sure enough, if enter following in repl, commpiles fine:
val c: class[t] forsome { type t >: scala.nothing <: string } = "foo".getclass
Comments
Post a Comment