diff --git a/core/src/main/scala/cats/data/Const.scala b/core/src/main/scala/cats/data/Const.scala index a6e5646c7b9..c19fe2ce857 100644 --- a/core/src/main/scala/cats/data/Const.scala +++ b/core/src/main/scala/cats/data/Const.scala @@ -8,14 +8,14 @@ import cats.functor.Contravariant * [[Const]] can be seen as a type level version of `Function.const[A, B]: A => B => A` * B is set covariant to help type inference. */ -final case class Const[A, +B](getConst: A) { +final case class Const[A, B](getConst: A) { /** * changes the type of the second type parameter */ def retag[C]: Const[A, C] = this.asInstanceOf[Const[A, C]] - def combine[BB >: B](that: Const[A, BB])(implicit A: Semigroup[A]): Const[A, BB] = + def combine(that: Const[A, B])(implicit A: Semigroup[A]): Const[A, B] = Const(A.combine(getConst, that.getConst)) def traverseFilter[F[_], C](f: B => F[Option[C]])(implicit F: Applicative[F]): F[Const[A, C]] = @@ -24,13 +24,13 @@ final case class Const[A, +B](getConst: A) { def traverse[F[_], C](f: B => F[C])(implicit F: Applicative[F]): F[Const[A, C]] = F.pure(retag[C]) - def ===[BB >: B](that: Const[A, BB])(implicit A: Eq[A]): Boolean = + def ===(that: Const[A, B])(implicit A: Eq[A]): Boolean = A.eqv(getConst, that.getConst) - def partialCompare[BB >: B](that: Const[A, BB])(implicit A: PartialOrder[A]): Double = + def partialCompare(that: Const[A, B])(implicit A: PartialOrder[A]): Double = A.partialCompare(getConst, that.getConst) - def compare[BB >: B](that: Const[A, BB])(implicit A: Order[A]): Int = + def compare(that: Const[A, B])(implicit A: Order[A]): Int = A.compare(getConst, that.getConst) def show(implicit A: Show[A]): String = @@ -40,6 +40,20 @@ final case class Const[A, +B](getConst: A) { object Const extends ConstInstances { def empty[A, B](implicit A: Monoid[A]): Const[A, B] = Const(A.empty) + + final class OfPartiallyApplied[B] { + def apply[A](a: A): Const[A, B] = Const(a) + } + + /** + * Convenient syntax for creating a Const[A, B] from an `A` + * {{{ + * scala> import cats.data._ + * scala> Const.of[Int]("a") + * res0: Const[String, Int] = Const("a") + * }}} + */ + def of[B]: OfPartiallyApplied[B] = new OfPartiallyApplied } private[data] sealed abstract class ConstInstances extends ConstInstances0 { diff --git a/free/src/test/scala/cats/free/FreeTTests.scala b/free/src/test/scala/cats/free/FreeTTests.scala index 7beeb92a6b0..4457c0141ec 100644 --- a/free/src/test/scala/cats/free/FreeTTests.scala +++ b/free/src/test/scala/cats/free/FreeTTests.scala @@ -141,6 +141,11 @@ class FreeTTests extends CatsSuite { result.toString.length should be > 0 } + private[free] def liftTCompilationTests() = { + val a: Either[String, Int]= Right(42) + val b: FreeT[Option, Either[String, ?], Int] = FreeT.liftT(a) + } + } object FreeTTests extends FreeTTestsInstances { diff --git a/tests/src/test/scala/cats/tests/RegressionTests.scala b/tests/src/test/scala/cats/tests/RegressionTests.scala index e1a7b5620bc..cacd06504ec 100644 --- a/tests/src/test/scala/cats/tests/RegressionTests.scala +++ b/tests/src/test/scala/cats/tests/RegressionTests.scala @@ -85,7 +85,7 @@ class RegressionTests extends CatsSuite { test("#500: foldMap - traverse consistency") { assert( - List(1,2,3).traverse(i => Const(List(i))).getConst == List(1,2,3).foldMap(List(_)) + List(1,2,3).traverse(i => Const.of[List[Int]](List(i))).getConst == List(1,2,3).foldMap(List(_)) ) }