diff --git a/core/src/main/scala/cats/data/OneAnd.scala b/core/src/main/scala/cats/data/OneAnd.scala index cfa47b1baa..4674219b07 100644 --- a/core/src/main/scala/cats/data/OneAnd.scala +++ b/core/src/main/scala/cats/data/OneAnd.scala @@ -10,10 +10,10 @@ import scala.collection.mutable.ListBuffer * used to represent a List which is guaranteed to not be empty: * * {{{ - * type NonEmptyList[A] = OneAnd[A, List] + * type NonEmptyList[A] = OneAnd[List, A] * }}} */ -final case class OneAnd[A, F[_]](head: A, tail: F[A]) { +final case class OneAnd[F[_], A](head: A, tail: F[A]) { /** * Combine the head and tail into a single `F[A]` value. @@ -32,7 +32,7 @@ final case class OneAnd[A, F[_]](head: A, tail: F[A]) { /** * Append another OneAnd to this */ - def combine(other: OneAnd[A, F])(implicit F: MonadCombine[F]): OneAnd[A, F] = + def combine(other: OneAnd[F, A])(implicit F: MonadCombine[F]): OneAnd[F, A] = OneAnd(head, F.combine(tail, F.combine(F.pure(other.head), other.tail))) /** @@ -69,11 +69,11 @@ final case class OneAnd[A, F[_]](head: A, tail: F[A]) { * Typesafe equality operator. * * This method is similar to == except that it only allows two - * OneAnd[A, F] values to be compared to each other, and uses + * OneAnd[F, A] values to be compared to each other, and uses * equality provided by Eq[_] instances, rather than using the * universal equality provided by .equals. */ - def ===(that: OneAnd[A, F])(implicit A: Eq[A], FA: Eq[F[A]]): Boolean = + def ===(that: OneAnd[F, A])(implicit A: Eq[A], FA: Eq[F[A]]): Boolean = A.eqv(head, that.head) && FA.eqv(tail, that.tail) /** @@ -89,41 +89,41 @@ final case class OneAnd[A, F[_]](head: A, tail: F[A]) { trait OneAndInstances extends OneAndLowPriority1 { - implicit def oneAndEq[A, F[_]](implicit A: Eq[A], FA: Eq[F[A]]): Eq[OneAnd[A, F]] = - new Eq[OneAnd[A, F]]{ - def eqv(x: OneAnd[A, F], y: OneAnd[A, F]): Boolean = x === y + implicit def oneAndEq[A, F[_]](implicit A: Eq[A], FA: Eq[F[A]]): Eq[OneAnd[F, A]] = + new Eq[OneAnd[F, A]]{ + def eqv(x: OneAnd[F, A], y: OneAnd[F, A]): Boolean = x === y } - implicit def oneAndShow[A, F[_]](implicit A: Show[A], FA: Show[F[A]]): Show[OneAnd[A, F]] = - Show.show[OneAnd[A, F]](_.show) + implicit def oneAndShow[A, F[_]](implicit A: Show[A], FA: Show[F[A]]): Show[OneAnd[F, A]] = + Show.show[OneAnd[F, A]](_.show) - implicit def oneAndSemigroupK[F[_]: MonadCombine]: SemigroupK[OneAnd[?, F]] = - new SemigroupK[OneAnd[?, F]] { - def combine[A](a: OneAnd[A, F], b: OneAnd[A, F]): OneAnd[A, F] = + implicit def oneAndSemigroupK[F[_]: MonadCombine]: SemigroupK[OneAnd[F, ?]] = + new SemigroupK[OneAnd[F, ?]] { + def combine[A](a: OneAnd[F, A], b: OneAnd[F, A]): OneAnd[F, A] = a combine b } - implicit def oneAndSemigroup[F[_]: MonadCombine, A]: Semigroup[OneAnd[A, F]] = + implicit def oneAndSemigroup[F[_]: MonadCombine, A]: Semigroup[OneAnd[F, A]] = oneAndSemigroupK.algebra - implicit def oneAndFoldable[F[_]](implicit foldable: Foldable[F]): Foldable[OneAnd[?,F]] = - new Foldable[OneAnd[?,F]] { - override def foldLeft[A, B](fa: OneAnd[A, F], b: B)(f: (B, A) => B): B = + implicit def oneAndFoldable[F[_]](implicit foldable: Foldable[F]): Foldable[OneAnd[F, ?]] = + new Foldable[OneAnd[F, ?]] { + override def foldLeft[A, B](fa: OneAnd[F, A], b: B)(f: (B, A) => B): B = fa.foldLeft(b)(f) - override def foldRight[A, B](fa: OneAnd[A, F], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = + override def foldRight[A, B](fa: OneAnd[F, A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = fa.foldRight(lb)(f) - override def isEmpty[A](fa: OneAnd[A, F]): Boolean = false + override def isEmpty[A](fa: OneAnd[F, A]): Boolean = false } - implicit def oneAndMonad[F[_]](implicit monad: MonadCombine[F]): Monad[OneAnd[?, F]] = - new Monad[OneAnd[?, F]] { - override def map[A, B](fa: OneAnd[A,F])(f: A => B): OneAnd[B, F] = + implicit def oneAndMonad[F[_]](implicit monad: MonadCombine[F]): Monad[OneAnd[F, ?]] = + new Monad[OneAnd[F, ?]] { + override def map[A, B](fa: OneAnd[F, A])(f: A => B): OneAnd[F, B] = OneAnd(f(fa.head), monad.map(fa.tail)(f)) - def pure[A](x: A): OneAnd[A, F] = + def pure[A](x: A): OneAnd[F, A] = OneAnd(x, monad.empty) - def flatMap[A, B](fa: OneAnd[A, F])(f: A => OneAnd[B, F]): OneAnd[B, F] = { + def flatMap[A, B](fa: OneAnd[F, A])(f: A => OneAnd[F, B]): OneAnd[F, B] = { val end = monad.flatMap(fa.tail) { a => val fa = f(a) monad.combine(monad.pure(fa.head), fa.tail) @@ -135,10 +135,10 @@ trait OneAndInstances extends OneAndLowPriority1 { } trait OneAndLowPriority0 { - implicit val nelComonad: Comonad[OneAnd[?, List]] = - new Comonad[OneAnd[?, List]] { + implicit val nelComonad: Comonad[OneAnd[List, ?]] = + new Comonad[OneAnd[List, ?]] { - def coflatMap[A, B](fa: OneAnd[A, List])(f: OneAnd[A, List] => B): OneAnd[B, List] = { + def coflatMap[A, B](fa: OneAnd[List, A])(f: OneAnd[List, A] => B): OneAnd[List, B] = { @tailrec def consume(as: List[A], buf: ListBuffer[B]): List[B] = as match { case Nil => buf.toList @@ -147,18 +147,18 @@ trait OneAndLowPriority0 { OneAnd(f(fa), consume(fa.tail, ListBuffer.empty)) } - def extract[A](fa: OneAnd[A, List]): A = + def extract[A](fa: OneAnd[List, A]): A = fa.head - def map[A, B](fa: OneAnd[A, List])(f: A => B): OneAnd[B, List] = + def map[A, B](fa: OneAnd[List, A])(f: A => B): OneAnd[List, B] = OneAnd(f(fa.head), fa.tail.map(f)) } } trait OneAndLowPriority1 extends OneAndLowPriority0 { - implicit def oneAndFunctor[F[_]](implicit F: Functor[F]): Functor[OneAnd[?, F]] = - new Functor[OneAnd[?, F]] { - def map[A, B](fa: OneAnd[A, F])(f: A => B): OneAnd[B, F] = + implicit def oneAndFunctor[F[_]](implicit F: Functor[F]): Functor[OneAnd[F, ?]] = + new Functor[OneAnd[F, ?]] { + def map[A, B](fa: OneAnd[F, A])(f: A => B): OneAnd[F, B] = OneAnd(f(fa.head), F.map(fa.tail)(f)) } } diff --git a/core/src/main/scala/cats/data/package.scala b/core/src/main/scala/cats/data/package.scala index f0380ee1f0..65078b8fc2 100644 --- a/core/src/main/scala/cats/data/package.scala +++ b/core/src/main/scala/cats/data/package.scala @@ -1,15 +1,15 @@ package cats package object data { - type NonEmptyList[A] = OneAnd[A, List] - type NonEmptyVector[A] = OneAnd[A, Vector] - type NonEmptyStream[A] = OneAnd[A, Stream] + type NonEmptyList[A] = OneAnd[List, A] + type NonEmptyVector[A] = OneAnd[Vector, A] + type NonEmptyStream[A] = OneAnd[Stream, A] type ValidatedNel[E, A] = Validated[NonEmptyList[E], A] def NonEmptyList[A](head: A, tail: List[A] = Nil): NonEmptyList[A] = OneAnd(head, tail) def NonEmptyList[A](head: A, tail: A*): NonEmptyList[A] = - OneAnd[A, List](head, tail.toList) + OneAnd[List, A](head, tail.toList) def NonEmptyVector[A](head: A, tail: Vector[A] = Vector.empty): NonEmptyVector[A] = OneAnd(head, tail) diff --git a/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala b/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala index 25f7320c89..b6eb269062 100644 --- a/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala +++ b/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala @@ -14,7 +14,7 @@ object arbitrary { implicit def constArbitrary[A, B](implicit A: Arbitrary[A]): Arbitrary[Const[A, B]] = Arbitrary(A.arbitrary.map(Const[A, B])) - implicit def oneAndArbitrary[F[_], A](implicit A: Arbitrary[A], F: Arbitrary[F[A]]): Arbitrary[OneAnd[A, F]] = + implicit def oneAndArbitrary[F[_], A](implicit A: Arbitrary[A], F: Arbitrary[F[A]]): Arbitrary[OneAnd[F, A]] = Arbitrary(F.arbitrary.flatMap(fa => A.arbitrary.map(a => OneAnd(a, fa)))) implicit def xorArbitrary[A, B](implicit A: Arbitrary[A], B: Arbitrary[B]): Arbitrary[A Xor B] = diff --git a/tests/src/test/scala/cats/tests/ListWrapper.scala b/tests/src/test/scala/cats/tests/ListWrapper.scala index e9205c0313..b8e15b16e5 100644 --- a/tests/src/test/scala/cats/tests/ListWrapper.scala +++ b/tests/src/test/scala/cats/tests/ListWrapper.scala @@ -91,9 +91,9 @@ object ListWrapper { def synthesize[A: Arbitrary]: Arbitrary[ListWrapper[A]] = implicitly } - implicit val listWrapperOneAndArbitraryK: ArbitraryK[OneAnd[?, ListWrapper]] = - new ArbitraryK[OneAnd[?, ListWrapper]] { - def synthesize[A: Arbitrary]: Arbitrary[OneAnd[A, ListWrapper]] = implicitly + implicit val listWrapperOneAndArbitraryK: ArbitraryK[OneAnd[ListWrapper, ?]] = + new ArbitraryK[OneAnd[ListWrapper, ?]] { + def synthesize[A: Arbitrary]: Arbitrary[OneAnd[ListWrapper, A]] = implicitly } implicit def listWrapperEq[A: Eq]: Eq[ListWrapper[A]] = Eq.by(_.list) diff --git a/tests/src/test/scala/cats/tests/OneAndTests.scala b/tests/src/test/scala/cats/tests/OneAndTests.scala index 3a1a057942..a6ab76b962 100644 --- a/tests/src/test/scala/cats/tests/OneAndTests.scala +++ b/tests/src/test/scala/cats/tests/OneAndTests.scala @@ -11,27 +11,27 @@ import cats.laws.discipline.arbitrary.{evalArbitrary, oneAndArbitrary} import scala.util.Random class OneAndTests extends CatsSuite { - checkAll("OneAnd[Int, List]", OrderLaws[OneAnd[Int, List]].eqv) + checkAll("OneAnd[List, Int]", OrderLaws[OneAnd[List, Int]].eqv) // Test instances that have more general constraints { implicit val functor = ListWrapper.functor - checkAll("OneAnd[Int, ListWrapper]", FunctorTests[OneAnd[?, ListWrapper]].functor[Int, Int, Int]) - checkAll("Functor[OneAnd[A, ListWrapper]]", SerializableTests.serializable(Functor[OneAnd[?, ListWrapper]])) + checkAll("OneAnd[ListWrapper, Int]", FunctorTests[OneAnd[ListWrapper, ?]].functor[Int, Int, Int]) + checkAll("Functor[OneAnd[ListWrapper, A]]", SerializableTests.serializable(Functor[OneAnd[ListWrapper, ?]])) } { implicit val monadCombine = ListWrapper.monadCombine - checkAll("OneAnd[Int, ListWrapper]", SemigroupKTests[OneAnd[?, ListWrapper]].semigroupK[Int]) - checkAll("OneAnd[Int, List]", GroupLaws[OneAnd[Int, List]].semigroup) - checkAll("SemigroupK[OneAnd[A, ListWrapper]]", SerializableTests.serializable(SemigroupK[OneAnd[?, ListWrapper]])) - checkAll("Semigroup[NonEmptyList[Int]]", SerializableTests.serializable(Semigroup[OneAnd[Int, List]])) + checkAll("OneAnd[ListWrapper, Int]", SemigroupKTests[OneAnd[ListWrapper, ?]].semigroupK[Int]) + checkAll("OneAnd[List, Int]", GroupLaws[OneAnd[List, Int]].semigroup) + checkAll("SemigroupK[OneAnd[ListWrapper, A]]", SerializableTests.serializable(SemigroupK[OneAnd[ListWrapper, ?]])) + checkAll("Semigroup[NonEmptyList[Int]]", SerializableTests.serializable(Semigroup[OneAnd[List, Int]])) } { implicit val foldable = ListWrapper.foldable - checkAll("OneAnd[Int, ListWrapper]", FoldableTests[OneAnd[?, ListWrapper]].foldable[Int, Int]) - checkAll("Foldable[OneAnd[A, ListWrapper]]", SerializableTests.serializable(Foldable[OneAnd[?, ListWrapper]])) + checkAll("OneAnd[ListWrapper, Int]", FoldableTests[OneAnd[ListWrapper, ?]].foldable[Int, Int]) + checkAll("Foldable[OneAnd[ListWrapper, A]]", SerializableTests.serializable(Foldable[OneAnd[ListWrapper, ?]])) } {