A Future That Cannot Fail In Scala

Is there a concept <<20> that can't fail in Scala?

I convert Future[Result] , which may not work, so I process both Failure and Success -into a Future[Option[String]] , which carry an optional error message derived from failure or success conditions. So far so good.

Now I would like to formally (i.e., using a type system) remember that this future will always contain Success and that I will not need to handle the case of a future failure.

Is there any reasonable way to do this?

+5
source share
2 answers

Isn't that the tag tags for?

 scala> type Tagged[U] = { type Tag = U } defined type alias Tagged scala> type @@[T, U] = T with Tagged[U] defined type alias $at$at scala> trait OK ; trait Uncertain defined trait OK defined trait Uncertain scala> type Sure[A] = Future[A] @@ OK defined type alias Sure scala> type Unsure[A] = Future[A] @@ Uncertain defined type alias Unsure scala> val f = Future.successful(42).asInstanceOf[Sure[Int]] f: Sure[Int] = Future(Success(42)) 

then

 scala> object X { def p(f: Sure[_]) = "sure" ; def p(f: Unsure[_])(implicit d: DummyImplicit) = "unsure" } defined object X scala> Xp(f) res1: String = sure 

Of course, he does not remain confident in the map.

+3
source

You cannot do this “using a type system” because there is no way for a type system to guarantee that Future will not fail, even if you promise it will not happen.

Consider this:

  Future { doStuff(); } .recover { case _ => "Failed!" } // Now it always succeeds .map { _ => Seq.empty[String].head } // Now it does not. 

Even if you intend to make any further transformations impossible once Future declared always successful, it still does not help, because the exception handler (or whatever you do to convert the original future to “always succeeding”) may throw.

Update: as indicated in the comment below, the above code snippet is incorrect: the .map result does not match Future as the .recover result. However, the point of view. Here is the correct illustration:

 Future { doStuff } .recover { case _ => Seq.empty[String].head } 
+6
source

Source: https://habr.com/ru/post/1245311/


All Articles