简体   繁体   中英

Difference between Class and Class.type in Scala

The following snippet explain my confusion:

scala> case class fellow[A, B](name:A, age:B)
class fellow

scala> :t -v fellow
// Type signature
fellow.type

// Internal Type structure
TypeRef(
  pre = ThisType(class $iw)
  TypeSymbol(class fellow extends Serializable)
)

scala> :kind -v fellow.type
fellow.type's kind is A
*
This is a proper type.

scala> :kind -v fellow
fellow's kind is F[A1,A2]
* -> * -> *
This is a type constructor: a 1st-order-kinded type.

Why fellow.type is different than fellow (as a type) I don't get why those two type are different, and why :t -v returns fellow.type ?

Write after this little experiment i checked against List and saw that it was the same

scala> :kind -v List
List's kind is F[+A]
* -(+)-> *
This is a type constructor: a 1st-order-kinded type.

scala> :kind -v List.type
scala.collection.immutable.List.type's kind is A
*
This is a proper type.

So what is the .type about exaxctly ? Where does it come from ? how does it differ from the other ... Trait Name, Class name

foo.type for any foo denotes the singleton type of foo , ie the type which has foo as its only instance. (Or, more precisely, for instances of AnyRef , the type which has only foo and null as its instances.) Please note that in the syntactic construction foo.type the foo part is a value (more precisely, a path to a value), whereas foo.type is a type .

Also, remember that a case class automatically generates a companion module of the same name, ie whenever you write

case class foo

there is also an implicit

object foo

So what is happening here, is that when you think you are asking for the type of the class foo , you are actually asking about the type of the singleton object foo . And the type of the singleton object foo is the singleton type foo.type , by definition.

I'll just add that besides :t in REPL you can use typeOf in ordinary Scala code

import scala.reflect.runtime.universe._

typeOf[fellow[_, _]].typeSymbol // class fellow
typeOf[fellow.type].typeSymbol // object fellow

ie a class and its companion object.

For values you can also do

def getType[A: TypeTag](a: A): Type = typeOf[A]

getType(fellow("a", 1)).typeSymbol // class fellow
getType(fellow).typeSymbol // object fellow

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM