我对理解type
中scala
的含义感到有些困惑。
在文档中我读到List[Int]
是一个类型而List是一个类型构造函数。
但是当我编写以下内容时,关键字type
意味着什么?
val ls: scala.collection.immutable.List.type = scala.collection.immutable.List
此type
如何与type
相关,可以将其定义为特征中的字段。
答案 0 :(得分:9)
当我编写以下内容时,关键字类型的含义
type
是Scala中object
上定义的成员。
假设您有一个类及其伴随对象:
class Foo(a: String)
object Foo {
def apply(a: String) = new Foo(a)
}
现在假设您要编写一个接受对象Foo
作为输入的方法。它的类型是什么?
如果你这样写:
def someMethod(fooObj: Foo) = fooObj.apply("x") // doesn't compile
它不会编译。 Foo
指的是类实例的类型(即new Foo("x")
或Foo("x")
返回的类型)。这就是为什么对象有type
成员可以引用他们自己的类型:
def someMethod(fooObj: Foo.type) = fooObj.apply("x") // compiles!
在您的具体示例中,List.type
是List
的伴随对象的类型。这里有几个例子,我希望能澄清它的含义:
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)
此类型如何与可以定义为特征中的字段的类型相关。例如。
type
关键字定义了一个类型成员。 .type
是类型成员。从概念上讲,它就像Scala中的每个对象都有一个名为type的类型成员,如下所示:
object Foo {
type type = Foo
}
显然这不会编译,但它会让你知道它的外观。
答案 1 :(得分:8)
如上所述的scala val
作业:
val name: Tpe = expression
Tpe
是标识符name
的类型。因此:
val x: List.type = List
List
对象(又名列表模块或列出随播广告)的类型为List.type
。这表明它是一个单身人士。所有这些都与类型理论中的类型构造函数的概念完全正交。
在类型理论中,List
(注意:不是伴侣)既是类型(表示为*
)又是类型构造函数(表示为* -> *
),因为当您提供类型参数时到List
(例如Int)然后你有一个类型(即List[Int]
)。 Scala为此构造提供了语法。例如:
def foo[F[_]]: F[Int]
^^^^ ^^^
| + supply a type argument to F[_]
|
+ the type constructor F[_]
但除非您对F
有更多了解,否则无法真正实现此类方法。例如,如果存在隐式scalaz.Monad[F]
,您可以使用Monad.pure
值构建F[Int]
,如下所示:
def foo[F[_]: Monad]: F[Int] = Monad[F].pure(1)
Scala确实允许您将List
作为类型构造函数传递给此类方法作为类型参数。例如:
scala> def foo[F[_]]: F[Int] = ???
foo: [F[_]]=> F[Int]
scala> lazy val x = foo[List]
x: List[Int] = <lazy>
但是,您在List
中提供的foo[List]
不是随播广告
请注意foo
的声明会产生以下警告:
<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] = ???
^
答案 2 :(得分:1)
在类型级编程中,您会认为List [+ A]是类型构造函数:
也就是说:
-List [+ A]采用类型参数(A),
-本身不是有效的类型,您需要以某种方式填写A-“构造类型”,
-通过用String填充,您将获得List [String],这是一种具体类型。
在Scala中,说某物属于List类型是无效的。 Scala在这里更加严格,并且不允许我们仅在类型的位置使用列表,因为它期望的是真实类型,而不是类型构造函数。
简而言之: List [+ A]是类型构造函数,而List [String]是实类型。