假设我需要在Scala中将Option[Int]
转换为Either[String, Int]
。我想这样做:
def foo(ox: Option[Int]): Either[String, Int] =
ox.fold(Left("No number")) {x => Right(x)}
字符串
不幸的是,上面的代码无法编译,我需要显式添加类型Either[String, Int]
:
ox.fold(Left("No number"): Either[String, Int]) { x => Right(x) }
型
是否可以将Option
转换为Either
而不添加类型?
如何将Option
转换为Either
?
4条答案
按热度按时间svujldwt1#
不,如果你这样做,你不能离开的类型。
Left("No number")
的类型被推断为Either[String, Nothing]
。仅从Left("No number")
编译器无法知道您希望Either
的第二个类型是Int
,并且类型推断不会走得太远,以至于编译器会查看整个方法并决定它应该是Either[String, Int]
。你可以用很多不同的方法来实现这一点。例如模式匹配:
字符串
或者使用
if
表达式:型
Either.cond
:型
7gs2gvoe2#
我不确定你当时使用的是哪个版本的Scala。目前,使用Scala 2.12.6,你的代码没有像这样的编译问题:
字符串
我想说的另一点是,折叠(虽然折叠是我的首选方法,它可以折叠几乎所有具有fold方法的东西)通常需要类型参数的帮助。编译器可以通过两种方式对表达式进行类型检查,要么推断类型参数,要么简单地找到显式定义的类型参数。
在你的例子中,如果你试图像这样折叠一个选项:
型
您显式地提供了关于第一个参数的类型信息,然后可以使用该信息来推断
fold
的类型参数。另一方面,您可以简单地显式地为
fold
提供类型参数,如下所示:型
现在你的实际(值级别)参数没有多余的类型信息,当编译器查看它时,没有类型推断,它可以立即告诉
fold
的类型参数是什么,因为它是显式提供的。使用方括号显式指定类型参数。还有一点,关于
x => Right(x)
,你实际上是在创建一个新的函数字面量,它只会将x传递给Right case类的同伴对象的apply
方法。你已经有了一个合适形状的函数。它接受x
并返回Right(x)
。它是apply
方法。你可以直接引用它(传递它)。型
gblwokeq3#
类型注解之所以是必要的,是因为Scala 2中类型推断对于多参数列表的工作方式,
考虑
Option#fold
的签名字符串
这里我们看到类型参数
B
和两个参数列表。现在提供给第一个参数列表的参数类型是Left[String,Nothing]
,因为型
这意味着类型参数
B
被推断为Left[String,Nothing]
,这又将提供给第二参数列表的自变量的预期类型约束为Left
返回类型的函数型
然而,我们提供了一个
Right
返回类型的函数,因此它会因类型不匹配而出错。型
请注意,Scala 3(Dotty)将improvements引入类型推断,因此您的代码片段可以开箱即用,而无需提供显式的类型注解
型
6fe3ivhb4#
最简单的方法是使用
Option.toRight
:字符串