From fd9b8558cda43fbd47f8cc04206048fd0b2afece Mon Sep 17 00:00:00 2001 From: Alexandru Nedelcu Date: Tue, 4 Apr 2017 15:34:06 +0300 Subject: [PATCH 1/2] Add Applicative#unit --- core/src/main/scala/cats/Applicative.scala | 8 ++++++++ laws/src/main/scala/cats/laws/ApplicativeLaws.scala | 3 +++ .../scala/cats/laws/discipline/ApplicativeTests.scala | 1 + 3 files changed, 12 insertions(+) diff --git a/core/src/main/scala/cats/Applicative.scala b/core/src/main/scala/cats/Applicative.scala index 3829d04c14..e418a8bfa8 100644 --- a/core/src/main/scala/cats/Applicative.scala +++ b/core/src/main/scala/cats/Applicative.scala @@ -22,6 +22,14 @@ import simulacrum.typeclass */ def pure[A](x: A): F[A] + /** + * Returns an `F[Unit]` instance, equivalent with `pure(())`. + * + * A useful shorthand, also allowing implementations to optimize the + * returned reference (e.g. it can be a `val`). + */ + def unit: F[Unit] = pure(()) + override def map[A, B](fa: F[A])(f: A => B): F[B] = ap(pure(f))(fa) diff --git a/laws/src/main/scala/cats/laws/ApplicativeLaws.scala b/laws/src/main/scala/cats/laws/ApplicativeLaws.scala index d7b496f371..a615c2525a 100644 --- a/laws/src/main/scala/cats/laws/ApplicativeLaws.scala +++ b/laws/src/main/scala/cats/laws/ApplicativeLaws.scala @@ -35,6 +35,9 @@ trait ApplicativeLaws[F[_]] extends ApplyLaws[F] { def apProductConsistent[A, B](fa: F[A], f: F[A => B]): IsEq[F[B]] = F.ap(f)(fa) <-> F.map(F.product(f, fa)) { case (f, a) => f(a) } + def applicativeUnit[A](a: A): IsEq[F[A]] = + F.unit.map(_ => a) <-> F.pure(a) + // The following are the lax monoidal functor identity laws - the associativity law is covered by // Cartesian's associativity law. diff --git a/laws/src/main/scala/cats/laws/discipline/ApplicativeTests.scala b/laws/src/main/scala/cats/laws/discipline/ApplicativeTests.scala index 60256cc9eb..6904efab24 100644 --- a/laws/src/main/scala/cats/laws/discipline/ApplicativeTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ApplicativeTests.scala @@ -31,6 +31,7 @@ trait ApplicativeTests[F[_]] extends ApplyTests[F] { "applicative homomorphism" -> forAll(laws.applicativeHomomorphism[A, B] _), "applicative interchange" -> forAll(laws.applicativeInterchange[A, B] _), "applicative map" -> forAll(laws.applicativeMap[A, B] _), + "applicative unit" -> forAll(laws.applicativeUnit[A] _), "ap consistent with product + map" -> forAll(laws.apProductConsistent[A, B] _), "monoidal left identity" -> forAll((fa: F[A]) => iso.leftIdentity(laws.monoidalLeftIdentity(fa))), "monoidal right identity" -> forAll((fa: F[A]) => iso.rightIdentity(laws.monoidalRightIdentity(fa)))) From dba946c162aad86ffee67d0a340997b2a1d60c23 Mon Sep 17 00:00:00 2001 From: Alexandru Nedelcu Date: Tue, 4 Apr 2017 15:39:29 +0300 Subject: [PATCH 2/2] Fix comment --- core/src/main/scala/cats/Applicative.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/cats/Applicative.scala b/core/src/main/scala/cats/Applicative.scala index e418a8bfa8..889922d9cd 100644 --- a/core/src/main/scala/cats/Applicative.scala +++ b/core/src/main/scala/cats/Applicative.scala @@ -23,7 +23,7 @@ import simulacrum.typeclass def pure[A](x: A): F[A] /** - * Returns an `F[Unit]` instance, equivalent with `pure(())`. + * Returns an `F[Unit]` value, equivalent with `pure(())`. * * A useful shorthand, also allowing implementations to optimize the * returned reference (e.g. it can be a `val`).