Для понимания просто синтаксический сахар для последовательности 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?
}
Ключевое слово if
для понимания используется для охранников :
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)
}
Но это не похоже на то, что вы хотите.Похоже, вы пытаетесь отслеживать исключения при выполнении каждого шага.Try
Монада делает именно это и может быть использована для понимания.Обратите внимание на эквивалентный код Scala, который использует flatMap
вызовы вместо для понимания.Я рекомендую написать функцию со всеми вложенными вызовами 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
}
}
}
}