我有以下功能:
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]
?
答案 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)
因为None
是Option[Nothing]
的子类型。 Nothing
是一切的子类型。 Option
在其类型参数中是协变的,因此Option[Nothing]
是Option[B]
的子类型(无论B
是什么)。
所以,第一次编译是因为None
是Option[B]
的子类型。
第二个无法编译,因为Option[String]
不是Option[B]
的子类型(可能是在调用时,但编译器不会知道)。