如何编译知道它是错误的

时间:2017-05-05 06:53:23

标签: scala

我有以下功能:

def apply[A,B](fa: Option[A])(ff: Option[A => B]): Option[B] = (fa, ff) match {
  case (None, _) => None
  case (Some(_), None) => None
  case (Some(a), Some(f)) => Some(f(a))
}

它编译得很好。

但是当我要改变功能如下:

def apply[A,B](fa: Option[A])(ff: Option[A => B]): Option[B] = (fa, ff) match {
  case (None, _) => None
  case (Some(_), None) => Some("Hello")
  case (Some(a), Some(f)) => Some(f(a))
}

编译器抱怨函数不符合Option[B]类型。

如果我将传递给apply函数Some(1)并返回Some("Hello"),我会得到另一种类型然后输入,然后在我看来它返回另一种类型然后输入类型。

在第一个示例中,编译器如何知道值类型不符合Option[B]以及为什么None符合Option[B]

2 个答案:

答案 0 :(得分:3)

1st - None是所有Option[]类型的有效值。换句话说......

val optx: Option[X] = None

...适用于任何类型X

第二 - 编译器对B了解多少? ff,如果不是None,则会生成B类型的输出,并且此apply()方法的输出必须属于同一类型,即{{1} },但包裹在B

Option,即Some("Hello"),不符合Option[String],因为编译器未被告知Option[B]仅限于生成ff输出。

答案 1 :(得分:1)

因为NoneOption[Nothing]的子类型。 Nothing是一切的子类型。 Option在其类型参数中是协变的,因此Option[Nothing]Option[B]的子类型(无论B是什么)。

所以,第一次编译是因为NoneOption[B]的子类型。 第二个无法编译,因为Option[String]不是Option[B]的子类型(可能是在调用时,但编译器不会知道)。