diff --git a/src/main/scala/applicative/Applicative.scala b/src/main/scala/applicative/Applicative.scala index baf28032adb822c6b0d70e5d44f1f9e97e71af3e..10a35fe163247eb6fe152ad3bb4c0a20b1042525 100644 --- a/src/main/scala/applicative/Applicative.scala +++ b/src/main/scala/applicative/Applicative.scala @@ -3,26 +3,26 @@ package applicative import scala.language.higherKinds trait Applicative[F[_]] { - def unit[A](a: A): F[A] + def pure[A](a: A): F[A] def ap[A, B](ff: F[A => B])(fa: F[A]): F[B] = map2(ff, fa)((f, a) => f(a)) - // implement map using unit and ap, but not flatMap/flatten + // implement map using pure and ap, but not flatMap/flatten def map[A, B](fa: F[A])(f: A => B): F[B] = ??? - // implement map2 using unit and ap + // implement map2 using pure and ap // hint: f.curried converts `(A,B) => C` to `A => (B => C)` def map2[A, B, C](fa: F[A], fb: F[B])(f: (A, B) => C): F[C] = ??? - // implement unit first + // implement pure first // then write the signature for ap and map2 // then implement one of them def compose[G[_]](implicit G: Applicative[G]): Applicative[Lambda[a => F[G[a]]]] = { val F = this new Applicative[Lambda[a => F[G[a]]]] { - def unit[A](a: A): F[G[A]] = ??? + def pure[A](a: A): F[G[A]] = ??? //note: when you are done implementing this, the test for ap/map2 will result in a StackOverflow until you implement one of them diff --git a/src/main/scala/applicative/Monad.scala b/src/main/scala/applicative/Monad.scala index 1455cae42461a088f7f524f3f731ff2c0cc178a1..d01043db9d0c9fc51ffdb2d81abd2d69e9cbdf8b 100644 --- a/src/main/scala/applicative/Monad.scala +++ b/src/main/scala/applicative/Monad.scala @@ -6,6 +6,6 @@ trait Monad[F[_]] extends Applicative[F] { def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] = flatten(map(fa)(f)) def flatten[A](fa: F[F[A]]): F[A] = flatMap(fa)(identity) - override def map[A, B](fa: F[A])(f: A => B): F[B] = flatMap(fa)(f andThen unit) + override def map[A, B](fa: F[A])(f: A => B): F[B] = flatMap(fa)(f andThen pure) override def map2[A, B, C](fa: F[A], fb: F[B])(f: (A, B) => C): F[C] = flatMap(fa)(a => map(fb)(b => f(a,b))) } diff --git a/src/main/scala/applicative/Validated.scala b/src/main/scala/applicative/Validated.scala index 879f3735106a4f936f1c785382b24e9498794269..3261f9a7a3a21fc3379913d8504f478bde079278 100644 --- a/src/main/scala/applicative/Validated.scala +++ b/src/main/scala/applicative/Validated.scala @@ -6,7 +6,7 @@ case class Invalid[+E](head: E, tail: List[E] = List()) extends Validated[E, Not object Validated { implicit def validatedApplicative[E]: Applicative[Validated[E, +?]] = new Applicative[Validated[E,+?]] { - def unit[A](a: A) = Valid(a) + def pure[A](a: A) = Valid(a) // add map2 or ap here } } diff --git a/src/main/scala/monads/MonadFunctor.scala b/src/main/scala/monads/MonadFunctor.scala index 19f6e236ec83b415e2cdcb33f791b6aa92f218be..d8e4e41e3f7306c15df274d0b999c58e6e31be78 100644 --- a/src/main/scala/monads/MonadFunctor.scala +++ b/src/main/scala/monads/MonadFunctor.scala @@ -2,7 +2,7 @@ package monads import scala.language.higherKinds trait Monad[F[_]] { - def unit[A](a: A): F[A] + def pure[A](a: A): F[A] def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] def map2[A, B, C](fa: F[A], fb: F[B])(f: (A, B) => C): F[C] = ??? diff --git a/src/main/scala/monads/MonadId.scala b/src/main/scala/monads/MonadId.scala index 013824c0b44883b766949dcff32b2dcfd6d414a1..f0c2e5e898e009a73544fcde29ea8595ea75ff1f 100644 --- a/src/main/scala/monads/MonadId.scala +++ b/src/main/scala/monads/MonadId.scala @@ -4,7 +4,7 @@ final case class Id[A](value: A) object Id { // No tests. If it compiles, it's correct. implicit val idMonad = new Monad[Id] { - def unit[A](a: A): Id[A] = ??? + def pure[A](a: A): Id[A] = ??? def flatMap[A, B](fa: Id[A])(f: A => Id[B]): Id[B] = ??? } } diff --git a/src/main/scala/parsers/lib/Parser.scala b/src/main/scala/parsers/lib/Parser.scala index dff394767aae2d4ce0290c0bb18b96010339f9e2..aa84db04bd4f8fb0b6776b42a03d73b10b02fa73 100644 --- a/src/main/scala/parsers/lib/Parser.scala +++ b/src/main/scala/parsers/lib/Parser.scala @@ -11,7 +11,7 @@ trait Parser[+A] { object Parser { implicit val parserMonad: Monad[Parser] = new Monad[Parser] { - def unit[A](a: A): Parser[A] = success(a) + def pure[A](a: A): Parser[A] = success(a) def flatMap[A, B](fa: Parser[A])(f: A => Parser[B]): Parser[B] = input => fa.parse(input) match { diff --git a/src/main/scala/parsers/lib/Parsers.scala b/src/main/scala/parsers/lib/Parsers.scala index 0494c0bb6b3c81e26403aecedba7ceba80b33e2f..ff23f454bb388a92af1d9bdc5118016439226f25 100644 --- a/src/main/scala/parsers/lib/Parsers.scala +++ b/src/main/scala/parsers/lib/Parsers.scala @@ -49,7 +49,7 @@ object Parsers extends Parsers { a <- p tail <- many(p) } yield a :: tail - ) | Monad[Parser].unit(Nil) + ) | Monad[Parser].pure(Nil) def manyN[A](p: Parser[A], n: Int): Parser[List[A]] = implicitly[Traverse[List]].sequence(List.fill(n)(p)) diff --git a/src/main/scala/parsers/lib/Typeclasses.scala b/src/main/scala/parsers/lib/Typeclasses.scala index 41d74e3b4e4ed3a269972a0df378ddc6a6812046..35e137f9d4289f764c0dbf9b98280f623e001537 100644 --- a/src/main/scala/parsers/lib/Typeclasses.scala +++ b/src/main/scala/parsers/lib/Typeclasses.scala @@ -3,7 +3,7 @@ package parsers.lib object Id { type Id[A] = A implicit val idMonad: Monad[Id] = new Monad[Id] { - override def unit[A](a:A): Id[A] = a + override def pure[A](a:A): Id[A] = a override def flatMap[A,B](a:Id[A])(f: A => Id[B]): Id[B] = f(a) } } @@ -17,10 +17,10 @@ object Functor { } trait Applicative[F[_]] extends Functor[F] { - def unit[A](a: A): F[A] + def pure[A](a: A): F[A] def ap[A, B](ff: F[A => B])(fa: F[A]): F[B] = map2(ff, fa)((f, a) => f(a)) - def map[A, B](fa: F[A])(f: A => B): F[B] = ap(unit(f))(fa) + def map[A, B](fa: F[A])(f: A => B): F[B] = ap(pure(f))(fa) def map2[A, B, C](fa: F[A], fb: F[B])(f: (A, B) => C): F[C] = ap(map(fa)(a => (b:B) => f(a,b)))(fb) } @@ -32,7 +32,7 @@ trait Monad[F[_]] extends Applicative[F] { def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] def flatten[A](fa: F[F[A]]): F[A] = flatMap(fa)(identity) - override def map[A, B](fa: F[A])(f: A => B): F[B] = flatMap(fa)(f andThen unit) + override def map[A, B](fa: F[A])(f: A => B): F[B] = flatMap(fa)(f andThen pure) override def map2[A, B, C](fa: F[A], fb: F[B])(f: (A, B) => C): F[C] = flatMap(fa)(a => map(fb)(b => f(a,b))) } @@ -61,7 +61,7 @@ object Traverse { implicit val listTraverse: Traverse[List] = new Traverse[List] { override def traverse[G[_], A, B](fa: List[A])(f: A => G[B])(implicit G: Applicative[G]): G[List[B]] = - fa.foldRight(G.unit(List[B]()))((a, b) => G.map2(f(a), b)(_ :: _)) + fa.foldRight(G.pure(List[B]()))((a, b) => G.map2(f(a), b)(_ :: _)) } } diff --git a/src/main/scala/readerwriter/internal/Reader.scala b/src/main/scala/readerwriter/internal/Reader.scala index ce27edd7aa79a8ecb71ab3f53e5d2ca26db687da..c5550564a45fa83bd0c260a9994b41bdcda9b694 100644 --- a/src/main/scala/readerwriter/internal/Reader.scala +++ b/src/main/scala/readerwriter/internal/Reader.scala @@ -12,7 +12,7 @@ object Reader { val a = fa.run(in) f(a).run(in) }) - override def unit[A](a: A): Reader[R, A] = Reader(_ => a) + override def pure[A](a: A): Reader[R, A] = Reader(_ => a) override def map2[A, B, C](fa: Reader[R, A], fb: Reader[R, B])(f: (A, B) => C): Reader[R, C] = Reader(in => { val a = fa.run(in) val b = fb.run(in) diff --git a/src/main/scala/readerwriter/internal/State.scala b/src/main/scala/readerwriter/internal/State.scala index 2d93948190db057c8f91d26f59e0e7488dd134de..0d877514f90f7469f9d508efc9e70a843cc0829f 100644 --- a/src/main/scala/readerwriter/internal/State.scala +++ b/src/main/scala/readerwriter/internal/State.scala @@ -9,7 +9,7 @@ case class State[S, A] private (run: S => (S, A)) case object State { implicit def stateMonad[S]: Monad[State[S, ?]] = new Monad[State[S, ?]] { - override def unit[A](a: A): State[S, A] = State(s => (s, a)) + override def pure[A](a: A): State[S, A] = State(s => (s, a)) override def flatMap[A, B](fa: State[S, A])(f: A => State[S, B]): State[S, B] = State(s => { val (s1, a) = fa.run(s) f(a).run(s1) diff --git a/src/main/scala/readerwriter/internal/Writer.scala b/src/main/scala/readerwriter/internal/Writer.scala index 1c9ccf849d70d162fbf4457a427ec0a37a24a77d..0cd1ab02fbc6dbebb167a09ac3e19f916d210c49 100644 --- a/src/main/scala/readerwriter/internal/Writer.scala +++ b/src/main/scala/readerwriter/internal/Writer.scala @@ -19,7 +19,7 @@ object Writer { Writer((implicitly[Monoid[L]].op(fa.v._1, next.v._1), next.v._2)) } - def unit[A](a: A): Writer[L, A] = Writer((implicitly[Monoid[L]].zero, a)) + def pure[A](a: A): Writer[L, A] = Writer((implicitly[Monoid[L]].zero, a)) override def map2[A, B, C](fa: Writer[L, A], fb: Writer[L, B])(f: (A, B) => C): Writer[L, C] = Writer((implicitly[Monoid[L]].op(fa.v._1, fb.v._1), f(fa.v._2, fb.v._2))) override def map[A, B](fa: Writer[L, A])(f: A => B): Writer[L, B] = Writer((fa.v._1, f(fa.v._2))) diff --git a/src/main/scala/traverse/Fuse.scala b/src/main/scala/traverse/Fuse.scala index 3f92ceea633403883cc7d831e2a3a3f57b5d9c5c..ca36a88061345e75ad7bd7197513579c24b9645a 100644 --- a/src/main/scala/traverse/Fuse.scala +++ b/src/main/scala/traverse/Fuse.scala @@ -25,15 +25,15 @@ object Fuse { def apply[A,B](fab: F[A => B])(fa: F[A]): F[B] = map2(fab, fa)(_(_)) - def unit[A](a: => A): F[A] + def pure[A](a: => A): F[A] def map[A,B](fa: F[A])(f: A => B): F[B] = - apply(unit(f))(fa) + apply(pure(f))(fa) def product[G[_]](G: Applicative[G]): Applicative[Lambda[x => (F[x], G[x])]] = { val self = this new Applicative[Lambda[x => (F[x], G[x])]]{ - def unit[A](a: => A) = (self.unit(a), G.unit(a)) + def pure[A](a: => A) = (self.pure(a), G.pure(a)) override def apply[A,B](fs: (F[A => B], G[A => B]))(p: (F[A], G[A])) = (self.apply(fs._1)(p._1), G.apply(fs._2)(p._2)) } diff --git a/src/main/scala/traverse/SequenceMap.scala b/src/main/scala/traverse/SequenceMap.scala index 56577f7526e834dca485a66e7aa37b9184df4cb3..4469078544f72956b2ee8a664909772d06b9d4d6 100644 --- a/src/main/scala/traverse/SequenceMap.scala +++ b/src/main/scala/traverse/SequenceMap.scala @@ -4,25 +4,25 @@ object SequenceMap { def sequenceMap[K,V](m: Map[K, F[V]]): F[Map[K,V]] = ??? //you can use any of these methods - def unit[A](a: => A): F[A] + def pure[A](a: => A): F[A] def apply[A,B](fab: F[A => B])(fa: F[A]): F[B] = map2(fab, fa)((ab, a) => ab(a)) - def map[A,B](fa: F[A])(f: A => B): F[B] = apply(unit(f))(fa) + def map[A,B](fa: F[A])(f: A => B): F[B] = apply(pure(f))(fa) def map2[A,B,C](fa: F[A], fb: F[B])(f: (A, B) => C): F[C] = - apply(apply(unit(f.curried))(fa))(fb) + apply(apply(pure(f.curried))(fa))(fb) def map3[A,B,C,D](fa: F[A], fb: F[B], fc: F[C])(f: (A, B, C) => D): F[D] = - apply(apply(apply(unit(f.curried))(fa))(fb))(fc) + apply(apply(apply(pure(f.curried))(fa))(fb))(fc) def factor[A,B](fa: F[A], fb: F[B]): F[(A,B)] = map2(fa, fb)((_,_)) def sequence[A](fas: List[F[A]]): F[List[A]] = - fas.foldRight[F[List[A]]](unit(Nil))((a, b) => map2(a, b)(_::_)) + fas.foldRight[F[List[A]]](pure(Nil))((a, b) => map2(a, b)(_::_)) def traverse[A,B](fas: List[A])(f: A => F[B]): F[List[B]] = - fas.foldRight[F[List[B]]](unit(Nil))((a, b) => map2(f(a), b)(_::_)) + fas.foldRight[F[List[B]]](pure(Nil))((a, b) => map2(f(a), b)(_::_)) } } diff --git a/src/test/scala/applicative/ApplicativeSpec.scala b/src/test/scala/applicative/ApplicativeSpec.scala index 58468199fd9bd6cf11c1c7b7ffe8c4aed2e83976..ab3d7ee7bb7b95f17d98cc457c9a416005f168bf 100644 --- a/src/test/scala/applicative/ApplicativeSpec.scala +++ b/src/test/scala/applicative/ApplicativeSpec.scala @@ -5,11 +5,11 @@ import testutil.PendingIfUnimplemented class ApplicativeSpec extends FlatSpec with Matchers with AppendedClues with PendingIfUnimplemented { implicit val optionApplicative = new Applicative[Option] { - override def unit[A](a: A): Option[A] = Some(a) + override def pure[A](a: A): Option[A] = Some(a) override def ap[A, B](ff: Option[A => B])(fa: Option[A]): Option[B] = ff.flatMap(f => fa.map(f)) } implicit val listApplicative = new Applicative[List] { - override def unit[A](a: A): List[A] = List(a) + override def pure[A](a: A): List[A] = List(a) override def ap[A, B](ff: List[A => B])(fa: List[A]): List[B] = ff.flatMap(f => fa.map(f)) } @@ -33,10 +33,10 @@ class ApplicativeSpec extends FlatSpec with Matchers with AppendedClues with Pen optionApplicative.map2(Some(2), Option.empty[Int])((a, b) => a + b) shouldBe None } - "compose" should "create nested element with unit" in { + "compose" should "create nested element with pure" in { val ola: Applicative[Lambda[a => Option[List[a]]]] = optionApplicative.compose(listApplicative) - ola.unit(5) shouldBe Some(List(5)) + ola.pure(5) shouldBe Some(List(5)) } it should "implement map2 or ap correctly" in { diff --git a/src/test/scala/monads/MonadFunctorSpec.scala b/src/test/scala/monads/MonadFunctorSpec.scala index 6f672b5f13574d2b3b1b1d71e06f5b9fe8bb5c3b..56923d0e28098e466cfd487431a0dcb25ac9ec48 100644 --- a/src/test/scala/monads/MonadFunctorSpec.scala +++ b/src/test/scala/monads/MonadFunctorSpec.scala @@ -6,7 +6,7 @@ import testutil.PendingIfUnimplemented class MonadFunctorSpec extends FlatSpec with Matchers with AppendedClues with PendingIfUnimplemented { "functorFromMonad" should "return a working functor" in { Functor.functorFromMonad[Option](new Monad[Option] { - def unit[A](a: A): Option[A] = Some(a) + def pure[A](a: A): Option[A] = Some(a) def flatMap[A, B](fa: Option[A])(f: A => Option[B]): Option[B] = fa.flatMap(f) }).map[Int, String](Some(3))(_.toString) shouldBe Some("3") diff --git a/src/test/scala/monads/MonadSpec.scala b/src/test/scala/monads/MonadSpec.scala index dc8c4ac93e3ce7bec6bee85c04067803cec0ff27..6a856c6083bdd3a43a37edf9dd97abb5faf922db 100644 --- a/src/test/scala/monads/MonadSpec.scala +++ b/src/test/scala/monads/MonadSpec.scala @@ -24,7 +24,7 @@ class MonadSpec extends FlatSpec with Matchers with AppendedClues with PendingIf } val tupleMonad = new Monad[Tuple1] { - def unit[A](a: A): Tuple1[A] = Tuple1(a) + def pure[A](a: A): Tuple1[A] = Tuple1(a) def flatMap[A, B](fa: Tuple1[A])(f: A => Tuple1[B]): Tuple1[B] = f(fa._1) }