Skip to main content

OptionT

Extension Methods for OptionT

import extras.cats.syntax.option._

or

import extras.cats.syntax.all._

optionT / t for F[Option[A]]

When you have foa: F[Option[A]], instead of OptionT(foa), you can simply do

foa.optionT // OptionT[F, A]
// or
foa.t // OptionT[F, A]
import cats.syntax.all._
import cats.effect._

import extras.cats.syntax.all._

val foa = IO.pure(1.some)
// foa: IO[Option[Int]] = Pure(a = Some(value = 1))
foa.t
// res1: cats.data.OptionT[IO, Int] = OptionT(
// value = Pure(a = Some(value = 1))
// )

val f = IO(println("Hello").some)
// f: IO[Option[Unit]] = Delay(
// thunk = <function0>,
// trace = StackTrace(
// stackTrace = List(
// cats.effect.internals.IOTracing$.buildFrame(IOTracing.scala:48),
// cats.effect.internals.IOTracing$.buildCachedFrame(IOTracing.scala:39),
// cats.effect.internals.IOTracing$.cached(IOTracing.scala:34),
// cats.effect.IO$.delay(IO.scala:1176),
// cats.effect.IO$.apply(IO.scala:1144),
// repl.MdocSession$App0$.<clinit>(optiont.md:26),
// repl.MdocSession$App.<init>(optiont.md:5),
// repl.MdocSession$.app(optiont.md:3),
// mdoc.internal.document.DocumentBuilder$$doc$.$anonfun$build$2(DocumentBuilder.scala:89),
// scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18),
// scala.util.DynamicVariable.withValue(DynamicVariable.scala:59),
// scala.Console$.withErr(Console.scala:193),
// mdoc.internal.document.DocumentBuilder$$doc$.$anonfun$build$1(DocumentBuilder.scala:89),
// scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18),
// scala.util.DynamicVariable.withValue(DynamicVariable.scala:59),
// scala.Console$.withOut(Console.scala:164),
// mdoc.internal.document.DocumentBuilder$$doc$.build(DocumentBuilder.scala:88),
// mdoc.internal.markdown.MarkdownBuilder$.$anonfun$buildDocument$2(MarkdownBuilder.scala:47),
// mdoc.internal.markdown.MarkdownBuilder$$anon$1.run(MarkdownBuilder.scala:104)
// )
// )
// )
f.t
// res2: cats.data.OptionT[IO, Unit] = OptionT(
// value = Delay(
// thunk = <function0>,
// trace = StackTrace(
// stackTrace = List(
// cats.effect.internals.IOTracing$.buildFrame(IOTracing.scala:48),
// cats.effect.internals.IOTracing$.buildCachedFrame(IOTracing.scala:39),
// cats.effect.internals.IOTracing$.cached(IOTracing.scala:34),
// cats.effect.IO$.delay(IO.scala:1176),
// cats.effect.IO$.apply(IO.scala:1144),
// repl.MdocSession$App0$.<clinit>(optiont.md:26),
// repl.MdocSession$App.<init>(optiont.md:5),
// repl.MdocSession$.app(optiont.md:3),
// mdoc.internal.document.DocumentBuilder$$doc$.$anonfun$build$2(DocumentBuilder.scala:89),
// scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18),
// scala.util.DynamicVariable.withValue(DynamicVariable.scala:59),
// scala.Console$.withErr(Console.scala:193),
// mdoc.internal.document.DocumentBuilder$$doc$.$anonfun$build$1(DocumentBuilder.scala:89),
// scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18),
// scala.util.DynamicVariable.withValue(DynamicVariable.scala:59),
// scala.Console$.withOut(Console.scala:164),
// mdoc.internal.document.DocumentBuilder$$doc$.build(DocumentBuilder.scala:88),
// mdoc.internal.markdown.MarkdownBuilder$.$anonfun$buildDocument$2(MarkdownBuilder.scala:47),
// mdoc.internal.markdown.MarkdownBuilder$$anon$1.run(MarkdownBuilder.scala:104)
// )
// )
// )
// )

optionT / t for Option[A]

When you have oa: Option[A], instead of OptionT.fromOption[F](oa), you can simply do

oa.optionT[F] // OptionT[F, A]
// or
oa.t[F] // OptionT[F, A]
import cats.syntax.all._
import cats.effect._

import extras.cats.syntax.all._

val oa = 1.some
// oa: Option[Int] = Some(value = 1)
oa.t[IO]
// res4: cats.data.OptionT[IO, Int] = OptionT(
// value = Pure(a = Some(value = 1))
// )

someT for F[A]

When you have fa: F[A], instead of OptionT.liftF(fa), you can simply do

fa.someT // OptionT[F, A]
import cats.effect._

import extras.cats.syntax.all._

val fa = IO.pure(1)
// fa: IO[Int] = Pure(a = 1)
fa.someT
// res6: cats.data.OptionT[IO, Int] = OptionT(
// value = Map(
// source = Pure(a = 1),
// f = cats.data.OptionT$$$Lambda$8253/0x00000001023e3040@7eaafa92,
// trace = StackTrace(
// stackTrace = List(
// cats.effect.internals.IOTracing$.buildFrame(IOTracing.scala:48),
// cats.effect.internals.IOTracing$.buildCachedFrame(IOTracing.scala:39),
// cats.effect.internals.IOTracing$.cached(IOTracing.scala:34),
// cats.effect.IO.map(IO.scala:106),
// cats.effect.IOLowPriorityInstances$IOEffect.map(IO.scala:872),
// cats.effect.IOLowPriorityInstances$IOEffect.map(IO.scala:865),
// cats.data.OptionT$.liftF(OptionT.scala:249),
// extras.cats.syntax.OptionSyntax$OptionTFAOps$.someT$extension(OptionSyntax.scala:37),
// repl.MdocSession$App5$.<clinit>(optiont.md:68),
// repl.MdocSession$App3$.<clinit>(optiont.md:53),
// repl.MdocSession$App0$.<clinit>(optiont.md:32),
// repl.MdocSession$App.<init>(optiont.md:5),
// repl.MdocSession$.app(optiont.md:3),
// mdoc.internal.document.DocumentBuilder$$doc$.$anonfun$build$2(DocumentBuilder.scala:89),
// scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18),
// scala.util.DynamicVariable.withValue(DynamicVariable.scala:59),
// scala.Console$.withErr(Console.scala:193),
// mdoc.internal.document.DocumentBuilder$$doc$.$anonfun$build$1(DocumentBuilder.scala:89),
// scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18),
// scala.util.DynamicVariable.withValue(DynamicVariable.scala:59),
// scala.Console$.withOut(Console.scala:164),
// mdoc.internal.document.DocumentBuilder$$doc$.build(DocumentBuilder.scala:88),
// mdoc.internal.markdown.MarkdownBuilder$.$anonfun$buildDocument$2(MarkdownBuilder.scala:47),
// mdoc.internal.markdown.MarkdownBuilder$$anon$1.run(MarkdownBuilder.scala:104)
// )
// )
// )
// )

val f = IO(println("Hello"))
// f: IO[Unit] = Delay(
// thunk = <function0>,
// trace = StackTrace(
// stackTrace = List(
// cats.effect.internals.IOTracing$.buildFrame(IOTracing.scala:48),
// cats.effect.internals.IOTracing$.buildCachedFrame(IOTracing.scala:39),
// cats.effect.internals.IOTracing$.cached(IOTracing.scala:34),
// cats.effect.IO$.delay(IO.scala:1176),
// cats.effect.IO$.apply(IO.scala:1144),
// repl.MdocSession$App5$.<clinit>(optiont.md:71),
// repl.MdocSession$App3$.<clinit>(optiont.md:53),
// repl.MdocSession$App0$.<clinit>(optiont.md:32),
// repl.MdocSession$App.<init>(optiont.md:5),
// repl.MdocSession$.app(optiont.md:3),
// mdoc.internal.document.DocumentBuilder$$doc$.$anonfun$build$2(DocumentBuilder.scala:89),
// scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18),
// scala.util.DynamicVariable.withValue(DynamicVariable.scala:59),
// scala.Console$.withErr(Console.scala:193),
// mdoc.internal.document.DocumentBuilder$$doc$.$anonfun$build$1(DocumentBuilder.scala:89),
// scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18),
// scala.util.DynamicVariable.withValue(DynamicVariable.scala:59),
// scala.Console$.withOut(Console.scala:164),
// mdoc.internal.document.DocumentBuilder$$doc$.build(DocumentBuilder.scala:88),
// mdoc.internal.markdown.MarkdownBuilder$.$anonfun$buildDocument$2(MarkdownBuilder.scala:47),
// mdoc.internal.markdown.MarkdownBuilder$$anon$1.run(MarkdownBuilder.scala:104)
// )
// )
// )
f.someT
// res7: cats.data.OptionT[IO, Unit] = OptionT(
// value = Map(
// source = Delay(
// thunk = <function0>,
// trace = StackTrace(
// stackTrace = List(
// cats.effect.internals.IOTracing$.buildFrame(IOTracing.scala:48),
// cats.effect.internals.IOTracing$.buildCachedFrame(IOTracing.scala:39),
// cats.effect.internals.IOTracing$.cached(IOTracing.scala:34),
// cats.effect.IO$.delay(IO.scala:1176),
// cats.effect.IO$.apply(IO.scala:1144),
// repl.MdocSession$App5$.<clinit>(optiont.md:71),
// repl.MdocSession$App3$.<clinit>(optiont.md:53),
// repl.MdocSession$App0$.<clinit>(optiont.md:32),
// repl.MdocSession$App.<init>(optiont.md:5),
// repl.MdocSession$.app(optiont.md:3),
// mdoc.internal.document.DocumentBuilder$$doc$.$anonfun$build$2(DocumentBuilder.scala:89),
// scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18),
// scala.util.DynamicVariable.withValue(DynamicVariable.scala:59),
// scala.Console$.withErr(Console.scala:193),
// mdoc.internal.document.DocumentBuilder$$doc$.$anonfun$build$1(DocumentBuilder.scala:89),
// scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18),
// scala.util.DynamicVariable.withValue(DynamicVariable.scala:59),
// scala.Console$.withOut(Console.scala:164),
// mdoc.internal.document.DocumentBuilder$$doc$.build(DocumentBuilder.scala:88),
// mdoc.internal.markdown.MarkdownBuilder$.$anonfun$buildDocument$2(MarkdownBuilder.scala:47),
// mdoc.internal.markdown.MarkdownBuilder$$anon$1.run(MarkdownBuilder.scala:104)
// )
// )
// ),
// f = cats.data.OptionT$$$Lambda$8253/0x00000001023e3040@7eaafa92,
// trace = StackTrace(
// stackTrace = List(
// cats.effect.internals.IOTracing$.buildFrame(IOTracing.scala:48),
// cats.effect.internals.IOTracing$.buildCachedFrame(IOTracing.scala:39),
// cats.effect.internals.IOTracing$.cached(IOTracing.scala:34),
// cats.effect.IO.map(IO.scala:106),
// cats.effect.IOLowPriorityInstances$IOEffect.map(IO.scala:872),
// cats.effect.IOLowPriorityInstances$IOEffect.map(IO.scala:865),
// cats.data.OptionT$.liftF(OptionT.scala:249),
// extras.cats.syntax.OptionSyntax$OptionTFAOps$.someT$extension(OptionSyntax.scala:37),
// ...

someTF for A

When you have a: A, instead of OptionT.some(a), you can simply do

a.someTF[F] // OptionT[F, A]
import cats.effect._

import extras.cats.syntax.all._

val a = 1
// a: Int = 1
a.someTF[IO]
// res9: cats.data.OptionT[IO, Int] = OptionT(
// value = Pure(a = Some(value = 1))
// )

Example

import cats.syntax.all._
import cats.effect._

import extras.cats.syntax.all._

final case class MyError(message: String)

def foo[F[_]: Sync](n: Int): F[Int] = Sync[F].pure(n * 2)

def bar[F[_]: Sync](n: Int): F[Option[Int]] =
if (n < 0)
Sync[F].pure(none[Int])
else
Sync[F].pure((n + 100).some)

def divide[F[_]: Sync](a: Int, b: Int): F[Option[Int]] =
if (b == 0)
none[Int].pure[F]
else
Sync[F].delay((a / b).some)

def run[F[_]: Sync](): F[Option[Int]] = (for {
a <- foo(123).someT
b <- 2.someTF[F]
c <- bar(b).optionT
d <- divide(a, b).t
} yield d).value

println(run[IO]().unsafeRunSync())
// Some(123)