diff --git a/core/src/main/scala/cats/instances/either.scala b/core/src/main/scala/cats/instances/either.scala index d156458705..c7451b272a 100644 --- a/core/src/main/scala/cats/instances/either.scala +++ b/core/src/main/scala/cats/instances/either.scala @@ -37,6 +37,8 @@ trait EitherInstances extends cats.kernel.instances.EitherInstances { implicit def catsStdInstancesForEither[A] : MonadError[Either[A, *], A] with Traverse[Either[A, *]] with Align[Either[A, *]] = new MonadError[Either[A, *], A] with Traverse[Either[A, *]] with Align[Either[A, *]] { + override def unit: Either[A, Unit] = Either.unit + def pure[B](b: B): Either[A, B] = Right(b) def flatMap[B, C](fa: Either[A, B])(f: B => Either[A, C]): Either[A, C] = diff --git a/core/src/main/scala/cats/syntax/either.scala b/core/src/main/scala/cats/syntax/either.scala index 85dab384ac..dda9b5df67 100644 --- a/core/src/main/scala/cats/syntax/either.scala +++ b/core/src/main/scala/cats/syntax/either.scala @@ -357,6 +357,9 @@ final class EitherObjectOps(private val either: Either.type) extends AnyVal { // case None => left[A, B](ifNone) case Some(a) => right(a) } + + /** Cached value of `Right(())` to avoid allocations for a common case. */ + def unit[A]: Either[A, Unit] = EitherUtil.unit } final class LeftOps[A, B](private val left: Left[A, B]) extends AnyVal { @@ -456,4 +459,6 @@ private[cats] object EitherUtil { right.asInstanceOf[Either[C, B]] def rightCast[A, B, C](left: Left[A, B]): Either[A, C] = left.asInstanceOf[Either[A, C]] + + private[cats] val unit = Right(()) }