I am reading this documentation about lifting values into Monad Transformers.
Based on this I wrote the following code
import cats.data._
import cats.implicits._
type FutureOption[T] = OptionT[Future, T]
val x : FutureOption[Int] = 1.pure[FutureOption] // works
val y : FutureOption[Int] = OptionT.fromOption[Future](Some(10)) // works
val z : FutureOption[Int] = OptionT.liftF(Future.successful(10)) // works
Now if I try
val z = FutureOption[Int] = OptionT(Future.successful(Some(10)))
I get an error
cmd4.sc:1: no type parameters for method apply: (value: F[Option[A]])cats.data.OptionT[F,A] in object OptionT exist so that it can be applied to arguments (scala.concurrent.Future[Some[Int]])
--- because ---
argument expression's type is not compatible with formal parameter type;
found : scala.concurrent.Future[Some[Int]]
required: ?F[Option[?A]]
val x : OptionT[Future, Int] = OptionT(Future.successful(Some(10)))
^
cmd4.sc:1: type mismatch;
found : scala.concurrent.Future[Some[Int]]
required: F[Option[A]]
val x : OptionT[Future, Int] = OptionT(Future.successful(Some(10)))
^
cmd4.sc:1: type mismatch;
found : cats.data.OptionT[F,A]
required: cats.data.OptionT[scala.concurrent.Future,Int]
val x : OptionT[Future, Int] = OptionT(Future.successful(Some(10)))
The error is due to Scala type inference.
In absence of an explicit Option
type annotation, the type of Some(10)
is Some[Int]
which is a subtype of Option[Int]
. However OptionT
expects exactly Option
so it won't compile.
You can make it compile by doing
val z: FutureOption[Int] = OptionT(Future.successful(Option(10)))
or
val z: FutureOption[Int] = OptionT(Future.successful(Some(10): Option[Int]))