0

Option我最近对 ​​scala 的子类型系统有所了解,并对类型及其子类型的关系产生了好奇。我了解到以下陈述是正确的。

如果 A <: B,则 (A => C) >: (B => C)

另外,我理解这A <: B意味着存在一些B不能是A. 如果我将这些应用于Option类型,那么我会得到以下结果。为方便起见,我将跳过ⱯA.符号。

  1. Nothing<: Option[A],所以Option[A] => string<:Nothing => string
  2. 我想不出任何实例Nothing => string不是 的实例Option[A] => string,所以Nothing => string<:Option[A] => string
  3. Nothing => string(<: 和 >:) Option[A] => string,因此Nothing => string实际上等于Option[A] => string子类型化
  4. Option[A] => string<: Some[A] => string,所以Nothing => string<:Some[A] => string
  5. Some[A]<:Nothing

由于我强烈怀疑结果是否正确,我认为中间出了点问题。谁能解释这里发生了什么?

4

2 回答 2

2

我认为你混淆了一些东西。我认为这A -> B应该意味着A => B,一个函数 from Ato B。接下来,Nothing[A]不存在,仅Nothing是Scala中的底层类型(所有类型的子类型)。但可能你的意思是对象None(类型为None.type),它是Option.

那么您的第一个假设将是正确的:

implicitly[None.type <:< Option[_]]   // ok
implicitly[(Option[_] => String) <:< (None.type => String)]  // ok

我改写你的第二个假设:

我想不出任何实例None.type => String不是 的实例Option[A] => String,所以(None.type => String) <: (Option[A] => String)

这个假设是错误的:

implicitly[(None.type => String) <:< (Option[_] => String)]
error: Cannot prove that None.type => String <:< Option[_] => String.
       implicitly[(None.type => String) <:< (Option[_] => String)]
                 ^

可能很难想象,因为None没有添加任何不属于 Option. 但以一般动物(as Option)和特殊动物(as None)为例。

trait Animal  // aka Option
object Dog extends Animal { def bark() = "bark!" }
object Cat extends Animal { def purr() = "purr!" } // aka None

您的第二个假设将意味着(Cat => String) <: (Animal => String). 如果这是真的,则可能出现以下情况:

val fun: Animal => String = { c: Cat.type => c.purr }  // doesn't compile

让我们强制:

val fun: Animal => String = { c: Cat.type => c.purr } .asInstanceOf[Animal => String]
fun(Dog)  // try run this
java.lang.ClassCastException: Dog$ cannot be cast to Cat$
  ... 64 elided
于 2018-02-18T20:04:59.303 回答
0

我将简单地拆开每一步。

  1. Nothing不接受任何类型参数。您可能的意思是None,它是类型None.type,而它又是一个Option[Nothing].
  2. 为什么不?

-

def foo(n: None.type): String = "blah"
println(foo(None)) // ok
// println(foo(Some("string"))) // doesn't compile.
  1. 错误的。
  2. 传递性原则上是正确的,但前一步是错误的
  3. 错误,因为前面的步骤错误。为什么这个推理应该普遍成立并不完全清楚。

所以不行。现在你可以想到一个函数,它接受None但不是一般的Option.

注意:None.type是单例对象的类型None。一般来说,单例对象的类型ObjObj.type.

于 2018-02-18T20:04:20.630 回答