Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: Cats, OptionT[Future, T] and ApplicativeError

Some time ago I've started using Cats and found OptionT very useful to work with Future[Option[T]] in most cases. But I faced with one drawback, to use AplicativeError I need to define type alias type FutureOption[T] = OptionT[Future, X] to matching F[_] required by AplicativeError and explicitly specify the type of my expression as FutureOption[T].

type FutureOption[T] = OptionT[Future, T] // definition to match F[_] kind

val x = OptionT.liftF(Future.failed(new Exception("error"))) : FutureOption[String] // need to specify type explicitly
x.recover {
  case NonFatal(e) => "fixed"
}

If I remove type definition and explicit type specification of my expression the recover will not be available because OptionT[Future, T] don't match F[_], so it can't be converted implicitly to AplicativeErrorOps.

Unfortunately, the example below won't work because there is no recover method.

val x = OptionT.liftF(Future.failed(new Exception("error")))
x.recover {
  case NonFatal(e) => "fixed"
}

Is there any way to avoid such kind of boilerplate code? At least I want to avoid specifying expression types as FutureOption[T] explicitly.

like image 366
andrey.feoktistov Avatar asked Feb 23 '18 09:02

andrey.feoktistov


1 Answers

In addition to the other answer, I would like to suggest that you make sure you have -Ypartial-unification enabled for your build.

This is a fix for partial unification of type constructors. You can find a more detailed explanation about the fix here.

With partial unification enabled the code you provided in your question compiles fine. Please note that if you're using an IDE (e.g. Intellij) you might get "false negatives" (the code is underlined as incorrect and code completion doesn't work), but the scalac/sbt/gradle will compile it just fine.

like image 74
Denis Rosca Avatar answered Nov 15 '22 05:11

Denis Rosca