diff --git a/core/src/main/scala/cats/data/OptionT.scala b/core/src/main/scala/cats/data/OptionT.scala index 93a904bc5d..cff671687c 100644 --- a/core/src/main/scala/cats/data/OptionT.scala +++ b/core/src/main/scala/cats/data/OptionT.scala @@ -94,6 +94,13 @@ object OptionT extends OptionTInstances { def pure[F[_], A](a: A)(implicit F: Applicative[F]): OptionT[F, A] = OptionT(F.pure(Some(a))) + /** An alias for pure */ + def some[F[_], A](a: A)(implicit F: Applicative[F]): OptionT[F, A] = + pure(a) + + def none[F[_], A](implicit F: Applicative[F]) : OptionT[F, A] = + OptionT(F.pure(None)) + /** * Transforms an `Option` into an `OptionT`, lifted into the specified `Applicative`. * diff --git a/docs/src/main/tut/optiont.md b/docs/src/main/tut/optiont.md index 7d70b282e7..9125b0fcbf 100644 --- a/docs/src/main/tut/optiont.md +++ b/docs/src/main/tut/optiont.md @@ -72,6 +72,23 @@ val result: Future[Option[String]] = ot.value // Future(Some("Hello Jane Doe")) ``` +## From `A` to `OptionT[F,A]` + +If you have only an `A` and you wish to *lift* it into an `OptionT[F,A]` assuming you have an [`Applicative`]({{ site.baseurl }}/tut/applicative.html) instance for `F` you can use `some` which is an alias for `pure`. There also exists a `none` method which can be used to create an `OptionT[F,A]`, where the `Option` wrapped `A` type is actually a `None`: + +```tut:silent + +import cats.std.future._ + +val greet: OptionT[Future,String] = OptionT.pure("Hola!") + +val greetAlt: OptionT[Future,String] = OptionT.some("Hi!") + +val failedGreet: OptionT[Future,String] = OptionT.none + +``` + + ## Beyond map Sometimes the operation you want to perform on an `Future[Option[String]]` might not be as simple as just wrapping the `Option` method in a `Future.map` call. For example, what if we want to greet the customer with their custom greeting if it exists but otherwise fall back to a default `Future[String]` greeting? Without `OptionT`, this implementation might look like: diff --git a/tests/src/test/scala/cats/tests/OptionTTests.scala b/tests/src/test/scala/cats/tests/OptionTTests.scala index 044dec5037..8d9b67f18e 100644 --- a/tests/src/test/scala/cats/tests/OptionTTests.scala +++ b/tests/src/test/scala/cats/tests/OptionTTests.scala @@ -134,6 +134,10 @@ class OptionTTests extends CatsSuite { OptionT[Xor[String, ?], Int](xor).show should === ("Xor.Right(Some(1))") } + test("none") { + OptionT.none[List,Int] should === (OptionT[List,Int](List(None))) + } + test("implicit Show[OptionT] instance and explicit show method are consistent") { forAll { optionT: OptionT[List, Int] => optionT.show should === (implicitly[Show[OptionT[List, Int]]].show(optionT))