diff --git a/core/src/main/scala/cats/data/OptionT.scala b/core/src/main/scala/cats/data/OptionT.scala index 75d77e1812..201afa2bf6 100644 --- a/core/src/main/scala/cats/data/OptionT.scala +++ b/core/src/main/scala/cats/data/OptionT.scala @@ -88,6 +88,8 @@ final case class OptionT[F[_], A](value: F[Option[A]]) { def toLeft[R](right: => R)(implicit F: Functor[F]): XorT[F, A, R] = XorT(cata(Xor.Right(right), Xor.Left.apply)) + + def show(implicit F: Show[F[Option[A]]]): String = F.show(value) } object OptionT extends OptionTInstances { @@ -138,4 +140,7 @@ trait OptionTInstances extends OptionTInstances1 { } implicit def optionTEq[F[_], A](implicit FA: Eq[F[Option[A]]]): Eq[OptionT[F, A]] = FA.on(_.value) + + implicit def optionTShow[F[_], A](implicit F: Show[F[Option[A]]]): Show[OptionT[F, A]] = + functor.Contravariant[Show].contramap(F)(_.value) } diff --git a/core/src/main/scala/cats/std/option.scala b/core/src/main/scala/cats/std/option.scala index 9eab6351c3..748bba181c 100644 --- a/core/src/main/scala/cats/std/option.scala +++ b/core/src/main/scala/cats/std/option.scala @@ -79,6 +79,14 @@ trait OptionInstances extends OptionInstances1 { if (y.isDefined) -1 else 0 } } + + implicit def showOption[A](implicit A: Show[A]): Show[Option[A]] = + new Show[Option[A]] { + def show(fa: Option[A]): String = fa match { + case Some(a) => s"Some(${A.show(a)})" + case None => "None" + } + } } trait OptionInstances1 extends OptionInstances2 { diff --git a/tests/src/test/scala/cats/tests/OptionTTests.scala b/tests/src/test/scala/cats/tests/OptionTTests.scala index fe2174d7ac..5c509ef6c6 100644 --- a/tests/src/test/scala/cats/tests/OptionTTests.scala +++ b/tests/src/test/scala/cats/tests/OptionTTests.scala @@ -111,6 +111,11 @@ class OptionTTests extends CatsSuite { } } + test("show"){ + val xor: String Xor Option[Int] = Xor.right(Some(1)) + OptionT[Xor[String, ?], Int](xor).show should === ("Xor.Right(Some(1))") + } + checkAll("OptionT[List, Int]", MonadCombineTests[OptionT[List, ?]].monad[Int, Int, Int]) checkAll("MonadOptionT[List, ?]]", SerializableTests.serializable(Monad[OptionT[List, ?]])) diff --git a/tests/src/test/scala/cats/tests/OptionTests.scala b/tests/src/test/scala/cats/tests/OptionTests.scala index 86eab0f910..72702002ad 100644 --- a/tests/src/test/scala/cats/tests/OptionTests.scala +++ b/tests/src/test/scala/cats/tests/OptionTests.scala @@ -12,4 +12,13 @@ class OptionTests extends CatsSuite { checkAll("Option[Int] with Option", TraverseTests[Option].traverse[Int, Int, Int, Int, Option, Option]) checkAll("Traverse[Option]", SerializableTests.serializable(Traverse[Option])) + + test("show") { + none[Int].show should === ("None") + 1.some.show should === ("Some(1)") + + forAll { fs: Option[String] => + fs.show should === (fs.toString) + } + } }