I’m learning Scala with the official course on Coursera. I’m speaking Java quite fluent, but this is something new. I get a knot in my brain.
The last programming assesment deals with asynchronous programming. I struggle with implementing a method of the companion object:
case class WikiResult[A](value: Future[Either[Seq[WikiError], A]])
object WikiResult:
def successful[A](a: A): WikiResult[A] = WikiResult(Future.successful(Right[Seq[WikiError], A](a)))
def traverse[A, B](as: Seq[A])(f: A => WikiResult[B])(using ExecutionContext): WikiResult[Seq[B]] =
as match
case Seq() => WikiResult.successful(Seq.empty)
case _ => as.foldLeft(WikiResult.successful(Seq.empty))((wili, a) => {
val b = f(a)
b.value match
case Failure(_) => WikiResult.successful(Seq.empty)
case _ => WikiResult.successful(Seq.empty)
})
This of course is no complete solution but a try to get the syntax right.
If the given as is empty, i return a new WikiResult with an empty value sequence.
Else, i iterate over as (as hinted in the task) with foldleft(). For each value a in as, i call the given function f. b.value can have three different states: Success(Right(val: B)) if everything worked, Success(Left(errlist: Seq[WikiError])) if a domain error happened, or Failure(exc: WikiException) if a system failure occured.
ATM, i’m testing only for the last case. To avoid incompleteness, i add the generic case. In both cases, i simply return an empty result.
To my big surprise, i get this case is unreachable since type concurrent.Future[Either[Seq[wikigraph.errors.WikiError], B]] and class Failure are unrelated. Whereever i read about scala´s Future, i found that matches are done with Success and Failure. I cannot imagine what i did wrong?
IDE is IntelliJ IDEA Community Edition. Scala and JVM are provided by IDE.
I found a lot of "case unreachable" questions but none correlated to my problem.
Any hints?
TIA QNo
There are methods
Future.successful(...)andFuture.failed(...).But it's
Trythat is an ADT with two casesSuccessandFailure, notFutureThere is
.valuethat transforms a future intoOption[Try[T]]. The thing is that at current moment a future is not necessarily successful or failed, maybe it's not completed yet.If you want "to get
TfromFuture[T]" then you can block withAwait.resultor register a callback withfuture.onComplete(...). Or you can keep working withFutures. By the way, there isFuture.traverse.Using Cats,
https://scastie.scala-lang.org/DmytroMitin/c798BQMPT4iQHLEB8u30QQ/6