Scala 匹配运行计算的结果在中无效,以便理解
我在一个理解的框架内,我们一起组成多个操作。当每个步骤完成时,我需要使用Scala 匹配运行计算的结果在中无效,以便理解,scala,monads,scala-cats,for-comprehension,Scala,Monads,Scala Cats,For Comprehension,我在一个理解的框架内,我们一起组成多个操作。当每个步骤完成时,我需要使用MonadError.raiseError抛出一个错误,或者继续执行下一步(如果有效) def myFunc[F[_]: Monad](input: Input)(implicit err: MonadError) = { for { stepAResult <- runStepA(input) if (stepAResult.isInstanceOf[Invalid[_]) { err
MonadError.raiseError
抛出一个错误,或者继续执行下一步(如果有效)
def myFunc[F[_]: Monad](input: Input)(implicit err: MonadError) = {
for {
stepAResult <- runStepA(input)
if (stepAResult.isInstanceOf[Invalid[_]) {
err.raiseError(new Throwable("error 1"))
} else {
stepBResult<- runStepB(stepAResult.toOption.get, input)
if (stepBResult.isInstanceOf[Invalid[_]]) {
err.raiseError(new Throwable("error 2"))
} else {
stepCResult <- runStepC(stepBResult.toOption.get)
// check for invalid here again.
}
}
}
}
def myFunc[F[\ux]:Monad](输入:输入)(隐式错误:MonadError)={
为了{
stepAResult假设您可以控制“runStep”函数,我建议您修改它们以返回一个[Invalid,u]或[Invalid],这样,您就可以将它们组合成一个单独的函数,以便理解(我使用了Throwable而不是Invalid,但想法是一样的):
def raiseError(e:Throwable):单位=println(e.getMessage)
def firstMethod(v:Int):要么[Throwable,Int]=Right(v*2)
def secondMethod(v:Int):或者[Throwable,Int]=Try(v/0)。toEither
def thirdMethod(v:Int):任意[Throwable,Int]=Right(v*2)
val x=用于{
首先For comprehension只是一系列flatMap
调用的语法糖。因此,并非只有任何Scala代码都可以进入您的内部进行理解。以下是您试图做的不合法Scala的事情之一:
//This does not compile because normal if-else statements are not valid inside a for comprehension
object Example1 {
def f(o: Option[Int]): Option[Int] = for {
x <- o
if (x < 0) "return some value"
else { //attempting to continue the for comprehension
y <- o
}
} yield ??? //what would we yield here?
}
但这看起来不像你想要的。它看起来像是你在运行每一步的时候都在试图跟踪异常情况。Try
Monad正是这样做的,并且可以用于理解。请注意等效的Scala代码,它使用flatMap
调用而不是a来理解。我建议用all编写函数嵌套的flatMap
会在尝试转换为更漂亮的语法以便于理解之前调用,如果您陷入困境,请查看一些如何执行此操作的示例
// myFunc1 is equiv to myFunc2 is equiv to myFunc3
// they only differ in syntax
object Example3 {
import scala.util.Try
def runStepA[A](in: A): Try[A] = ???
def runStepB[A](in: A): Try[A] = ???
def runStepC[A](in: A): Try[A] = ???
def myFunc1[A](input: A): Try[A] = for {
nonErrorResultA <- runStepA(input)
nonErrorResultB <- runStepB(nonErrorResultA)
nonErrorResultC <- runStepC(nonErrorResultB)
} yield nonErrorResultC
def myFunc2[A](input: A): Try[A] =
runStepA(input).flatMap {
nonErrorResultA => runStepA(nonErrorResultA).flatMap {
nonErrorResultB => runStepB(nonErrorResultB).flatMap {
nonErrorResultC => runStepC(nonErrorResultC)
}
}
}
def myFunc3[A](input: A): Try[A] =
runStepA(input).flatMap {
runStepA(_).flatMap {
runStepB(_).flatMap {
runStepC
}
}
}
}
//myFunc1等同于myFunc2等同于myFunc3
//它们只是在语法上有所不同
对象示例3{
导入scala.util.Try
def runStepA[A](在:A中):尝试[A]=???
def runStepB[A](在:A中):尝试[A]=???
def runStepC[A](在:A中):尝试[A]=???
def myFunc1[A](输入:A):请尝试[A]=for{
非错误结果RUNSTEC(非错误结果)
}
}
}
def myFunc3[A](输入:A):尝试[A]=
runStepA(输入).flatMap{
runStepA(u).flatMap{
runStepB(41;).flatMap{
runStepC
}
}
}
}
您是否尝试过直接使用map
/flatMap
而不是使用for
?您可能应该使用match
而不是isInstanceOf
。您能给我举个例子说明在这种情况下如何做到这一点吗?我尝试了几种不同的方法,但代码无法编译。您需要给出更多信息在我们提出任何具体建议之前,请先了解类型的详细信息,但请记住,for(a…
object Example2 {
def f(o: Option[Int]): Option[Int] = for {
x <- o
if x >= 0
} yield x
//f and f2 are equivalent functions
def f2(l: Option[Int]): Option[Int] = l.filter(_ >= 0)
}
// myFunc1 is equiv to myFunc2 is equiv to myFunc3
// they only differ in syntax
object Example3 {
import scala.util.Try
def runStepA[A](in: A): Try[A] = ???
def runStepB[A](in: A): Try[A] = ???
def runStepC[A](in: A): Try[A] = ???
def myFunc1[A](input: A): Try[A] = for {
nonErrorResultA <- runStepA(input)
nonErrorResultB <- runStepB(nonErrorResultA)
nonErrorResultC <- runStepC(nonErrorResultB)
} yield nonErrorResultC
def myFunc2[A](input: A): Try[A] =
runStepA(input).flatMap {
nonErrorResultA => runStepA(nonErrorResultA).flatMap {
nonErrorResultB => runStepB(nonErrorResultB).flatMap {
nonErrorResultC => runStepC(nonErrorResultC)
}
}
}
def myFunc3[A](input: A): Try[A] =
runStepA(input).flatMap {
runStepA(_).flatMap {
runStepB(_).flatMap {
runStepC
}
}
}
}