The type of a block is the type of the last expression on the block. So
{ println(...); 2 }
has type Int
.
Difference between B
and C
is difference in type inference between type members and type parameters (1, 2).
object B{
def apply[T](c:T)={}
}
object C{
type T
def apply(c:T)={}
}
class C1[T]{
def apply(c:T)={}
}
val d: Unit = B{println(1);2}
// val e: Unit = C{println(1);2} // doesn't compile
val e1: Unit = (new C1){println(1);2}
// scalacOptions ++= Seq("-Xprint:typer", "-Xprint-types")
// val d: Unit = A.this{A.type}.B.apply{[T](c: T)Unit}[Int]{(c: Int)Unit}({
// scala.Predef.println{(x: Any)Unit}(1{Int(1)}){Unit};
// 2{Int(2)}
// }{2}){Unit};
// val e: Unit = A.this{A.type}.C.apply{(c: A.C.T)Unit}({
// println{<null>}(1{Int(1)}){<null>};
// 2{Int(2)}
// }{<null>}){<error>};
// val e1: Unit = new A.C1[Int]{A.C1[Int]}{()A.C1[Int]}(){A.C1[Int]}.apply{(c: Int)Unit}({
// scala.Predef.println{(x: Any)Unit}(1{Int(1)}){Unit};
// 2{Int(2)}
// }{2}){Unit};
In C
type T
remains abstract
Use of abstract type in a concrete class?
Concrete classes with abstract type members
There is thesis about type inference in Scala:
Plociniczak, Hubert ; Odersky, Martin. Decrypting Local Type Inference https://infoscience.epfl.ch/record/214757
If you want e
to compile you can specify T
val e: Unit = C.asInstanceOf[C.type{type T = Int}]{println(1);2}
def apply[T](c: T)
the T means "whatever the type ofc
is on each call". Whereas, on the second example the T is already set (in your specific example probably the compiler infers either Any or Nothing since you did not specified it). – Lymphoid{ println(...); 2 }
has type Int. – LymphoidT
will be inferredAny
orNothing
, I guess it will remain abstract. The error is "found:Int(2)
; required:C.T
" and not "found:Int(2)
; required:Nothing
" or "found:Int(2)
; required:Any
" #11275033 #2116178 – Neomineomycin