[英]Scala Yeild returning Try[Either[]] rather then Either
I am trying to do some handson with scala basic operations and got stuck here in the following sample code我正在尝试对 scala 基本操作进行一些动手操作,并在以下示例代码中陷入困境
def insuranceRateQuote(a: Int, tickets:Int) : Either[Exception, Double] = {
// ... something
Right(Double)
}
def parseInsuranceQuoteFromWebForm(age: String, numOfTickets: String) : Either[Exception, Double]= {
try{
val a = Try(age.toInt)
val tickets = Try(numOfTickets.toInt)
for{
aa <- a
t <- tickets
} yield insuranceRateQuote(aa,t) // ERROR HERE
} catch {
case _ => Left(new Exception)}
}
The Error I am getting is that it says found Try[Either[Exception,Double]]
我得到的错误是它说
found Try[Either[Exception,Double]]
I am not getting why it is wrapper under Try of Either我不明白为什么它是 Try of Either 下的包装器
PS - This must not be the perfect way to do in scala so feel free to post your sample code:) PS - 这一定不是在 scala 中做的完美方式,所以请随时发布您的示例代码:)
The key to understand is that for-comprehensions might transform what is inside the wrapper but will not change the wrapper itself.要理解的关键是,理解可能会改变包装器内部的内容,但不会改变包装器本身。 The reason is because for-comprehension de-sugar to
map
/ flatMap
calls on the wrapper determined in the first step of the chain.原因是因为对
map
/ flatMap
的理解脱糖调用链的第一步中确定的包装器。 For example consider the following snippet例如考虑以下代码片段
val result: Try[Int] = Try(41).map(v => v + 1)
// result: scala.util.Try[Int] = Success(42)
Note how we transformed the value inside the Try
wrapper from 41
to 42
however the wrapper remained unchanged.请注意我们如何将
Try
包装器中的值从41
转换为42
,但包装器保持不变。 Alternatively we could express the same thing using a for-comprehension或者,我们可以使用 for-comprehension 来表达同样的事情
val result: Try[Int] = for { v <- Try(41) } yield v + 1
// result: scala.util.Try[Int] = Success(42)
Note how the effect is exactly the same.注意效果是如何完全相同的。 Now consider the following for comprehension which chains multiple steps
现在考虑以下链接多个步骤的理解
val result: Try[Int] =
for {
a <- Try(41) // first step determines the wrapper for all the other steps
b <- Try(1)
} yield a + b
// result: scala.util.Try[Int] = Success(42)
This expands to这扩展到
val result: Try[Int] =
Try(41).flatMap { (a: Int) =>
Try(1).map { (b: Int) => a + b }
}
// result: scala.util.Try[Int] = Success(42)
where again we see the result is the same, namely, a value transformed inside the wrapper but wrapper remained untransformed.我们再次看到结果是相同的,即在包装器内部转换的值但包装器保持未转换。
Finally consider最后考虑
val result: Try[Either[Exception, Int]] =
for {
a <- Try(41) // first step still determines the top-level wrapper
b <- Try(1)
} yield Right(a + b) // here we wrap inside `Either`
// result: scala.util.Try[Either[Exception,Int]] = Success(Right(42))
The principle remains the same - we did wrap a + b
inside Either
however this does not affect the top-level outer wrapper which is still Try
.原理保持不变 - 我们确实将
a + b
包装在Either
中,但这不会影响仍然是Try
的顶级外部包装器。
Mario Galic's answer already explains the problem with your code, but I'd fix it differently. Mario Galic 的回答已经解释了您的代码的问题,但我会以不同的方式解决它。
Two points:两点:
Either[Exception, A]
(or rather, Either[Throwable, A]
) is kind of equivalent to Try[A]
, with Left
taking the role of Failure
and Right
the role of Success
. Either[Exception, A]
(或者更确切地说, Either[Throwable, A]
)有点等价于Try[A]
, Left
扮演Failure
角色, Right
扮演Success
角色。
The outer try
/ catch
is not useful because the exceptions should be captured by working in Try
.外部的
try
/ catch
没有用,因为异常应该通过在Try
中工作来捕获。
So you probably want something like所以你可能想要类似的东西
def insuranceRateQuote(a: Int, tickets:Int) : Try[Double] = {
// ... something
Success(someDouble)
}
def parseInsuranceQuoteFromWebForm(age: String, numOfTickets: String): Try[Double] = {
val a = Try(age.toInt)
val tickets = Try(numOfTickets.toInt)
for{
aa <- a
t <- tickets
q <- insuranceRateQuote(aa,t)
} yield q
}
A bit unfortunately, this does a useless map(q => q)
if you figure out what the comprehension does, so you can write it more directly as有点不幸的是,如果您弄清楚理解的作用,这会产生无用的
map(q => q)
,因此您可以更直接地将其编写为
a.flatMap(aa => tickets.flatMap(t => insuranceRateQuote(aa,t)))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.