Option类型的子类型关系

时间:2018-02-18 18:40:35

标签: scala type-theory subtyping

我最近学到了一些关于scala的子类型系统,我对Option类型及其子类型感到好奇。关系。我了解到以下陈述是正确的。

  

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

此外,我了解A <: B表示存在B的某个实例,该实例不能是A的实例。如果我将这些应用于Option类型,那么我会得到以下结果。为方便起见,我会跳过ⱯA.符号。

  1. Nothing&lt;:Option[A],所以Option[A] => string&lt;:Nothing => string
  2. 我无法想到Nothing => string的任何实例都不是Option[A] => string的实例,所以Nothing => string&lt;:Option[A] => string
  3. Nothing => string(&lt ;:和&gt; :) Option[A] => string,因此Nothing => string实际上等于子类型中的Option[A] => string
  4. Option[A] => string&lt;:Some[A] => string,所以Nothing => string&lt;:Some[A] => string
  5. Some[A]&lt;:Nothing
  6. 由于我强烈怀疑结果是否正确,我认为中间出了点问题。谁能解释一下这里发生了什么?

2 个答案:

答案 0 :(得分:2)

我认为你混淆了一些事情。我认为A -> B应该是A => B,是AB的函数。接下来,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界面的方法。但是采用一般动物(如Option)和特定动物(如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

答案 1 :(得分:0)

我只是分开每一步。

  1. Nothing不接受任何类型参数。您可能需要None,其类型为None.type,而Option[Nothing]则为def foo(n: None.type): String = "blah" println(foo(None)) // ok // println(foo(Some("string"))) // doesn't compile.
  2. 为什么不呢?
  3. -

    None
    1. 假。
    2. 原则上的传递性正确,但前一步错误
    3. 错,因为以前的步骤错了。为什么这种推理总体上应该保持不完全清楚。
    4. 所以,不。现在,您可以考虑一个需要Option而不是一般None.type的函数。

      注意:None是单例对象Obj的类型。通常,单例对象Obj.type的类型为Function<? extends T, ? extends U>