简体   繁体   中英

What is type and what is type constructor in scala

I'm a bit confused about understanding of what type in scala means.

In documents I read that List[Int] is a type and List is a type constructor.

but what keyword type means when I write the following?

val ls: scala.collection.immutable.List.type = scala.collection.immutable.List

And how this type related to type that can be defined as a field in a trait for example.

what keyword type means when I write the following

type is a member defined on object in Scala.

Suppose you have a class and its companion object:

class Foo(a: String)

object Foo {
  def apply(a: String) = new Foo(a)
}

Now suppose you want to write a method that accepts the object Foo as an input. What's its type?

If you write this:

def someMethod(fooObj: Foo) = fooObj.apply("x") // doesn't compile

it's not going to compile. Foo refers to the type of an instance of the class (ie the one returned by new Foo("x") or Foo("x") ). That's why objects have a type member that can refer to their own type:

def someMethod(fooObj: Foo.type) = fooObj.apply("x") // compiles!

In your specific example List.type is the type of the companion object of List . Here's a couple of examples that I hope will clarify what it means:

val listObj: List.type = List
val anEmptyList: List[Int] = listObj.empty[Int] // List()
val aListOfIntegers: List[Int] = listObj.range(1, 4) // List[(1, 2, 3)

And how this type related to type that can be defined as a field in a trait for example.

The type keyword defines a type member. .type is a type member. Conceptually it's like every object in Scala has a type member named type, like this:

object Foo {
  type type = Foo
}

Obviously this won't compile, but it gives you an idea of what it may look like.

In a scala val assignment like the above:

val name: Tpe = expression

Tpe is the type of the identifier name . Hence:

val x: List.type = List

The type of the List object (aka List module or List companion ) is List.type . This indicates that it is a singleton. All of this is completely orthogonal to the concept of a type constructor in type theory.

Type Constructors

In type theory, List (note: not the companion) is both a type (denoted * ) and a type constructor (denoted * -> * ) because when you supply a type argument to List (eg Int) then you have a type (ie List[Int] ). Scala provides syntax for this construction. For example:

def foo[F[_]]: F[Int]
        ^^^^     ^^^
         |        + supply a type argument to F[_]  
         |
         + the type constructor F[_] 

But you cannot really implement such a method unless you know more about F . For example, if there is a implicit scalaz.Monad[F] , you might use the Monad.pure value to construct your F[Int] like so:

def foo[F[_]: Monad]: F[Int] = Monad[F].pure(1)

In Scala

Scala does let you pass around List as a type constructor as a type parameter to such a method. For example:

scala> def foo[F[_]]: F[Int] = ???
foo: [F[_]]=> F[Int]

scala> lazy val x = foo[List]
x: List[Int] = <lazy>

However the List you are supplying in foo[List] is not the companion

Note the declaration of foo will result in the following warning:

<console>:11: warning: higher-kinded type should be enabled
by making the implicit value scala.language.higherKinds visible.
This can be achieved by adding the import clause 'import 
scala.language.higherKinds'
or by setting the compiler option -language:higherKinds.
See the Scaladoc for value scala.language.higherKinds for a discussion
why the feature should be explicitly enabled.
       def foo[F[_]]: F[Int] = ???
               ^

In type-level programming you'd think of a List[+A] being a type constructor:

That is:

-List[+A] takes a type parameter (A),

-by itself it's not a valid type, you need to fill in the A somehow - "construct the type",

-by filling it in with String you'd get List[String] which is a concrete type.

In Scala it is not valid to say something is of type List. Scala is more strict here, and won't allow us to use just a List in the place of a type, as it's expecting a real type - not a type constructor.

In brief: List[+A] is a type constructor whereas List[String] is a real type.

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