diff --git a/core/src/main/scala/cats/arrow/FunctionK.scala b/core/src/main/scala/cats/arrow/FunctionK.scala new file mode 100644 index 00000000000..5e1cf69a8aa --- /dev/null +++ b/core/src/main/scala/cats/arrow/FunctionK.scala @@ -0,0 +1,31 @@ +package cats +package arrow + +import cats.data.{Xor, Coproduct} + +trait FunctionK[F[_], G[_]] extends Serializable { self => + def apply[A](fa: F[A]): G[A] + + def compose[E[_]](f: FunctionK[E, F]): FunctionK[E, G] = + new FunctionK[E, G] { + def apply[A](fa: E[A]): G[A] = self.apply(f(fa)) + } + + def andThen[H[_]](f: FunctionK[G, H]): FunctionK[F, H] = + f.compose(self) + + def or[H[_]](h: FunctionK[H,G]): FunctionK[Coproduct[F, H, ?], G] = + new FunctionK[Coproduct[F, H, ?], G] { + def apply[A](fa: Coproduct[F, H, A]): G[A] = fa.run match { + case Xor.Left(ff) => self(ff) + case Xor.Right(gg) => h(gg) + } + } +} + +object FunctionK { + def id[F[_]]: FunctionK[F, F] = + new FunctionK[F, F] { + def apply[A](fa: F[A]): F[A] = fa + } +} diff --git a/core/src/main/scala/cats/arrow/NaturalTransformation.scala b/core/src/main/scala/cats/arrow/NaturalTransformation.scala deleted file mode 100644 index 0b792bc9cfe..00000000000 --- a/core/src/main/scala/cats/arrow/NaturalTransformation.scala +++ /dev/null @@ -1,31 +0,0 @@ -package cats -package arrow - -import cats.data.{Xor, Coproduct} - -trait NaturalTransformation[F[_], G[_]] extends Serializable { self => - def apply[A](fa: F[A]): G[A] - - def compose[E[_]](f: NaturalTransformation[E, F]): NaturalTransformation[E, G] = - new NaturalTransformation[E, G] { - def apply[A](fa: E[A]): G[A] = self.apply(f(fa)) - } - - def andThen[H[_]](f: NaturalTransformation[G, H]): NaturalTransformation[F, H] = - f.compose(self) - - def or[H[_]](h: NaturalTransformation[H,G]): NaturalTransformation[Coproduct[F, H, ?],G] = - new (NaturalTransformation[Coproduct[F, H, ?],G]) { - def apply[A](fa: Coproduct[F, H, A]): G[A] = fa.run match { - case Xor.Left(ff) => self(ff) - case Xor.Right(gg) => h(gg) - } - } -} - -object NaturalTransformation { - def id[F[_]]: NaturalTransformation[F, F] = - new NaturalTransformation[F, F] { - def apply[A](fa: F[A]): F[A] = fa - } -} diff --git a/core/src/main/scala/cats/data/Coproduct.scala b/core/src/main/scala/cats/data/Coproduct.scala index 1428abd123b..09a16e8f9ae 100644 --- a/core/src/main/scala/cats/data/Coproduct.scala +++ b/core/src/main/scala/cats/data/Coproduct.scala @@ -1,7 +1,7 @@ package cats package data -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.functor.Contravariant /** `F` on the left and `G` on the right of [[Xor]]. @@ -63,13 +63,13 @@ final case class Coproduct[F[_], G[_], A](run: F[A] Xor G[A]) { * * Example: * {{{ - * scala> import cats.arrow.NaturalTransformation + * scala> import cats.arrow.FunctionK * scala> import cats.data.Coproduct * scala> val listToOption = - * | new NaturalTransformation[List, Option] { + * | new FunctionK[List, Option] { * | def apply[A](fa: List[A]): Option[A] = fa.headOption * | } - * scala> val optionToOption = NaturalTransformation.id[Option] + * scala> val optionToOption = FunctionK.id[Option] * scala> val cp1: Coproduct[List, Option, Int] = Coproduct.leftc(List(1,2,3)) * scala> val cp2: Coproduct[List, Option, Int] = Coproduct.rightc(Some(4)) * scala> cp1.fold(listToOption, optionToOption) @@ -78,7 +78,7 @@ final case class Coproduct[F[_], G[_], A](run: F[A] Xor G[A]) { * res1: Option[Int] = Some(4) * }}} */ - def fold[H[_]](f: NaturalTransformation[F, H], g: NaturalTransformation[G, H]): H[A] = + def fold[H[_]](f: FunctionK[F, H], g: FunctionK[G, H]): H[A] = run.fold(f.apply, g.apply) } diff --git a/core/src/main/scala/cats/data/Kleisli.scala b/core/src/main/scala/cats/data/Kleisli.scala index ea4b58c33ca..6f06bb1e179 100644 --- a/core/src/main/scala/cats/data/Kleisli.scala +++ b/core/src/main/scala/cats/data/Kleisli.scala @@ -1,7 +1,7 @@ package cats package data -import cats.arrow.{Arrow, Choice, Split, NaturalTransformation} +import cats.arrow.{Arrow, Choice, Split, FunctionK} import cats.functor.{Contravariant, Strong} /** @@ -48,7 +48,7 @@ final case class Kleisli[F[_], A, B](run: A => F[B]) { self => def local[AA](f: AA => A): Kleisli[F, AA, B] = Kleisli(f.andThen(run)) - def transform[G[_]](f: NaturalTransformation[F,G]): Kleisli[G, A, B] = + def transform[G[_]](f: FunctionK[F,G]): Kleisli[G, A, B] = Kleisli(a => f(run(a))) def lower(implicit F: Applicative[F]): Kleisli[F, A, F[B]] = diff --git a/core/src/main/scala/cats/package.scala b/core/src/main/scala/cats/package.scala index d1e7ad5730d..106ab97364b 100644 --- a/core/src/main/scala/cats/package.scala +++ b/core/src/main/scala/cats/package.scala @@ -3,8 +3,7 @@ */ package object cats { - type ~>[F[_], G[_]] = arrow.NaturalTransformation[F, G] - type <~[F[_], G[_]] = arrow.NaturalTransformation[G, F] + type ~>[F[_], G[_]] = arrow.FunctionK[F, G] type ⊥ = Nothing type ⊤ = Any diff --git a/docs/src/main/tut/freeapplicative.md b/docs/src/main/tut/freeapplicative.md index 238d44ded1d..f9534a8e770 100644 --- a/docs/src/main/tut/freeapplicative.md +++ b/docs/src/main/tut/freeapplicative.md @@ -54,14 +54,14 @@ at this point. To make our program useful we need to interpret it. ```tut:silent import cats.Id -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.std.function._ // a function that takes a string as input type FromString[A] = String => A val compiler = - new NaturalTransformation[ValidationOp, FromString] { + new FunctionK[ValidationOp, FromString] { def apply[A](fa: ValidationOp[A]): String => A = str => fa match { @@ -103,7 +103,7 @@ import scala.concurrent.ExecutionContext.Implicits.global type ParValidator[A] = Kleisli[Future, String, A] val parCompiler = - new NaturalTransformation[ValidationOp, ParValidator] { + new FunctionK[ValidationOp, ParValidator] { def apply[A](fa: ValidationOp[A]): ParValidator[A] = Kleisli { str => fa match { @@ -130,7 +130,7 @@ import cats.std.list._ type Log[A] = Const[List[String], A] val logCompiler = - new NaturalTransformation[ValidationOp, Log] { + new FunctionK[ValidationOp, Log] { def apply[A](fa: ValidationOp[A]): Log[A] = fa match { case Size(size) => Const(List(s"size >= $size")) @@ -166,7 +166,7 @@ import cats.data.Prod type ValidateAndLog[A] = Prod[ParValidator, Log, A] val prodCompiler = - new NaturalTransformation[ValidationOp, ValidateAndLog] { + new FunctionK[ValidationOp, ValidateAndLog] { def apply[A](fa: ValidationOp[A]): ValidateAndLog[A] = { fa match { case Size(size) => diff --git a/docs/src/main/tut/freemonad.md b/docs/src/main/tut/freemonad.md index d8cf2a2848b..25636230918 100644 --- a/docs/src/main/tut/freemonad.md +++ b/docs/src/main/tut/freemonad.md @@ -166,14 +166,14 @@ DSL. By itself, this DSL only represents a sequence of operations To do this, we will use a *natural transformation* between type containers. Natural transformations go between types like `F[_]` and `G[_]` (this particular transformation would be written as -`NaturalTransformation[F,G]` or as done here using the symbolic +`FunctionK[F,G]` or as done here using the symbolic alternative as `F ~> G`). In our case, we will use a simple mutable map to represent our key value store: ```tut:silent -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.{Id, ~>} import scala.collection.mutable @@ -244,7 +244,7 @@ recursive structure by: This operation is called `Free.foldMap`: ```scala -final def foldMap[M[_]](f: NaturalTransformation[S,M])(M: Monad[M]): M[A] = ... +final def foldMap[M[_]](f: FunctionK[S,M])(M: Monad[M]): M[A] = ... ``` `M` must be a `Monad` to be flattenable (the famous monoid aspect @@ -366,7 +366,7 @@ def program(implicit I : Interacts[CatsApp], D : DataSource[CatsApp]): Free[Cats } ``` -Finally we write one interpreter per ADT and combine them with a `NaturalTransformation` to `Coproduct` so they can be +Finally we write one interpreter per ADT and combine them with a `FunctionK` to `Coproduct` so they can be compiled and applied to our `Free` program. ```tut:invisible diff --git a/free/src/main/scala/cats/free/Coyoneda.scala b/free/src/main/scala/cats/free/Coyoneda.scala index 9afa427ca34..2bf8ec57749 100644 --- a/free/src/main/scala/cats/free/Coyoneda.scala +++ b/free/src/main/scala/cats/free/Coyoneda.scala @@ -1,7 +1,7 @@ package cats package free -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK /** * The dual view of the Yoneda lemma. Also a free functor on `F`. @@ -38,7 +38,7 @@ sealed abstract class Coyoneda[F[_], A] extends Serializable { self => final def map[B](f: A => B): Aux[F, B, Pivot] = apply(fi)(f compose k) - final def transform[G[_]](f: NaturalTransformation[F,G]): Aux[G, A, Pivot] = + final def transform[G[_]](f: FunctionK[F,G]): Aux[G, A, Pivot] = apply(f(fi))(k) } diff --git a/free/src/main/scala/cats/free/Free.scala b/free/src/main/scala/cats/free/Free.scala index d6a14d3a704..b1cb8c213f8 100644 --- a/free/src/main/scala/cats/free/Free.scala +++ b/free/src/main/scala/cats/free/Free.scala @@ -4,7 +4,7 @@ package free import scala.annotation.tailrec import cats.data.Xor, Xor.{Left, Right} -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK object Free { /** @@ -130,7 +130,7 @@ sealed abstract class Free[S[_], A] extends Product with Serializable { * Run to completion, mapping the suspension with the given transformation at each step and * accumulating into the monad `M`. */ - final def foldMap[M[_]](f: NaturalTransformation[S,M])(implicit M: Monad[M]): M[A] = + final def foldMap[M[_]](f: FunctionK[S,M])(implicit M: Monad[M]): M[A] = step match { case Pure(a) => M.pure(a) case Suspend(s) => f(s) @@ -142,13 +142,13 @@ sealed abstract class Free[S[_], A] extends Product with Serializable { * using the given natural transformation. * Be careful if your natural transformation is effectful, effects are applied by mapSuspension. */ - final def mapSuspension[T[_]](f: NaturalTransformation[S,T]): Free[T, A] = + final def mapSuspension[T[_]](f: FunctionK[S,T]): Free[T, A] = foldMap[Free[T, ?]] { - new NaturalTransformation[S, Free[T, ?]] { + new FunctionK[S, Free[T, ?]] { def apply[B](fa: S[B]): Free[T, B] = Suspend(f(fa)) } }(Free.freeMonad) - final def compile[T[_]](f: NaturalTransformation[S,T]): Free[T, A] = mapSuspension(f) + final def compile[T[_]](f: FunctionK[S,T]): Free[T, A] = mapSuspension(f) } diff --git a/free/src/main/scala/cats/free/FreeApplicative.scala b/free/src/main/scala/cats/free/FreeApplicative.scala index e5a9268ac8f..b581ca5a4dc 100644 --- a/free/src/main/scala/cats/free/FreeApplicative.scala +++ b/free/src/main/scala/cats/free/FreeApplicative.scala @@ -1,7 +1,7 @@ package cats package free -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.data.Const /** Applicative Functor for Free */ @@ -27,7 +27,7 @@ sealed abstract class FreeApplicative[F[_], A] extends Product with Serializable /** Interprets/Runs the sequence of operations using the semantics of Applicative G * Tail recursive only if G provides tail recursive interpretation (ie G is FreeMonad) */ - final def foldMap[G[_]](f: NaturalTransformation[F,G])(implicit G: Applicative[G]): G[A] = + final def foldMap[G[_]](f: FunctionK[F,G])(implicit G: Applicative[G]): G[A] = this match { case Pure(a) => G.pure(a) case Ap(pivot, fn) => G.map2(f(pivot), fn.foldMap(f))((a, g) => g(a)) @@ -37,26 +37,26 @@ sealed abstract class FreeApplicative[F[_], A] extends Product with Serializable * Tail recursive only if `F` provides tail recursive interpretation. */ final def fold(implicit F: Applicative[F]): F[A] = - foldMap(NaturalTransformation.id[F]) + foldMap(FunctionK.id[F]) /** Interpret this algebra into another FreeApplicative */ - final def compile[G[_]](f: NaturalTransformation[F,G]): FA[G, A] = + final def compile[G[_]](f: FunctionK[F,G]): FA[G, A] = foldMap[FA[G, ?]] { - new NaturalTransformation[F, FA[G, ?]] { + new FunctionK[F, FA[G, ?]] { def apply[B](fa: F[B]): FA[G, B] = lift(f(fa)) } } /** Interpret this algebra into a Monoid */ - final def analyze[M:Monoid](f: NaturalTransformation[F,λ[α => M]]): M = - foldMap[Const[M, ?]](new (NaturalTransformation[F,Const[M, ?]]) { + final def analyze[M:Monoid](f: FunctionK[F,λ[α => M]]): M = + foldMap[Const[M, ?]](new (FunctionK[F,Const[M, ?]]) { def apply[X](x: F[X]): Const[M,X] = Const(f(x)) }).getConst /** Compile this FreeApplicative algebra into a Free algebra. */ final def monad: Free[F, A] = foldMap[Free[F, ?]] { - new NaturalTransformation[F, Free[F, ?]] { + new FunctionK[F, Free[F, ?]] { def apply[B](fa: F[B]): Free[F, B] = Free.liftF(fa) } } diff --git a/free/src/test/scala/cats/free/CoyonedaTests.scala b/free/src/test/scala/cats/free/CoyonedaTests.scala index 26cbe381939..45e708acfa7 100644 --- a/free/src/test/scala/cats/free/CoyonedaTests.scala +++ b/free/src/test/scala/cats/free/CoyonedaTests.scala @@ -2,7 +2,7 @@ package cats package free import cats.tests.CatsSuite -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.laws.discipline.{FunctorTests, SerializableTests} import org.scalacheck.Arbitrary @@ -27,7 +27,7 @@ class CoyonedaTests extends CatsSuite { test("transform and run is same as applying natural trans") { val nt = - new NaturalTransformation[Option, List] { + new FunctionK[Option, List] { def apply[A](fa: Option[A]): List[A] = fa.toList } val o = Option("hello") diff --git a/free/src/test/scala/cats/free/FreeApplicativeTests.scala b/free/src/test/scala/cats/free/FreeApplicativeTests.scala index de60d901eca..91096c92dfc 100644 --- a/free/src/test/scala/cats/free/FreeApplicativeTests.scala +++ b/free/src/test/scala/cats/free/FreeApplicativeTests.scala @@ -2,7 +2,7 @@ package cats package free import cats.tests.CatsSuite -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.laws.discipline.{CartesianTests, ApplicativeTests, SerializableTests} import cats.data.State @@ -18,7 +18,7 @@ class FreeApplicativeTests extends CatsSuite { implicit def freeApplicativeEq[S[_]: Applicative, A](implicit SA: Eq[S[A]]): Eq[FreeApplicative[S, A]] = new Eq[FreeApplicative[S, A]] { def eqv(a: FreeApplicative[S, A], b: FreeApplicative[S, A]): Boolean = { - val nt = NaturalTransformation.id[S] + val nt = FunctionK.id[S] SA.eqv(a.foldMap(nt), b.foldMap(nt)) } } @@ -44,7 +44,7 @@ class FreeApplicativeTests extends CatsSuite { val x = FreeApplicative.lift[Id, Int](1) val y = FreeApplicative.pure[Id, Int](2) val f = x.map(i => (j: Int) => i + j) - val nt = NaturalTransformation.id[Id] + val nt = FunctionK.id[Id] val r1 = y.ap(f) val r2 = r1.compile(nt) r1.foldMap(nt) should === (r2.foldMap(nt)) @@ -57,7 +57,7 @@ class FreeApplicativeTests extends CatsSuite { val r1 = y.ap(f) val r2 = r1.monad val nt = - new NaturalTransformation[Id, Id] { + new FunctionK[Id, Id] { def apply[A](fa: Id[A]): Id[A] = fa } r1.foldMap(nt) should === (r2.foldMap(nt)) @@ -75,7 +75,7 @@ class FreeApplicativeTests extends CatsSuite { test("FreeApplicative#analyze") { type G[A] = List[Int] - val countingNT = new NaturalTransformation[List, G] { + val countingNT = new FunctionK[List, G] { def apply[A](la: List[A]): G[A] = List(la.length) } @@ -97,7 +97,7 @@ class FreeApplicativeTests extends CatsSuite { type Tracked[A] = State[String, A] - val f: NaturalTransformation[Foo,Tracked] = new NaturalTransformation[Foo,Tracked] { + val f: FunctionK[Foo,Tracked] = new FunctionK[Foo,Tracked] { def apply[A](fa: Foo[A]): Tracked[A] = State[String, A]{ s0 => (s0 + fa.toString + ";", fa.getA) } @@ -120,7 +120,7 @@ class FreeApplicativeTests extends CatsSuite { val z = Apply[Dsl].map2(x, y)((_, _) => ()) - val asString: NaturalTransformation[Id,λ[α => String]] = new NaturalTransformation[Id,λ[α => String]] { + val asString: FunctionK[Id,λ[α => String]] = new FunctionK[Id,λ[α => String]] { def apply[A](a: A): String = a.toString } diff --git a/free/src/test/scala/cats/free/FreeTests.scala b/free/src/test/scala/cats/free/FreeTests.scala index 1b9c7d63bec..ff611907d70 100644 --- a/free/src/test/scala/cats/free/FreeTests.scala +++ b/free/src/test/scala/cats/free/FreeTests.scala @@ -2,7 +2,7 @@ package cats package free import cats.tests.CatsSuite -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.laws.discipline.{CartesianTests, MonadTests, SerializableTests} import cats.laws.discipline.arbitrary.function0Arbitrary @@ -19,7 +19,7 @@ class FreeTests extends CatsSuite { test("mapSuspension id"){ forAll { x: Free[List, Int] => - x.mapSuspension(NaturalTransformation.id[List]) should === (x) + x.mapSuspension(FunctionK.id[List]) should === (x) } } @@ -38,7 +38,7 @@ class FreeTests extends CatsSuite { test("mapSuspension consistent with foldMap"){ forAll { x: Free[List, Int] => val mapped = x.mapSuspension(headOptionU) - val folded = mapped.foldMap(NaturalTransformation.id[Option]) + val folded = mapped.foldMap(FunctionK.id[Option]) folded should === (x.foldMap(headOptionU)) } } @@ -56,7 +56,7 @@ class FreeTests extends CatsSuite { z <- if (j<10000) a(j) else Free.pure[FTestApi, Int](j) } yield z - def runner: NaturalTransformation[FTestApi,Id] = new NaturalTransformation[FTestApi,Id] { + def runner: FunctionK[FTestApi,Id] = new FunctionK[FTestApi,Id] { def apply[A](fa: FTestApi[A]): Id[A] = fa match { case TB(i) => i+1 } @@ -77,7 +77,7 @@ object FreeTests extends FreeTestsInstances { } sealed trait FreeTestsInstances { - val headOptionU: NaturalTransformation[List,Option] = new NaturalTransformation[List,Option] { + val headOptionU: FunctionK[List,Option] = new FunctionK[List,Option] { def apply[A](fa: List[A]): Option[A] = fa.headOption } diff --git a/free/src/test/scala/cats/free/InjectTests.scala b/free/src/test/scala/cats/free/InjectTests.scala index e957da6f00b..ae922e63bad 100644 --- a/free/src/test/scala/cats/free/InjectTests.scala +++ b/free/src/test/scala/cats/free/InjectTests.scala @@ -1,7 +1,7 @@ package cats package free -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.tests.CatsSuite import cats.data.{Xor, Coproduct} import org.scalacheck._ @@ -40,19 +40,19 @@ class InjectTests extends CatsSuite { implicit def test2Arbitrary[A](implicit seqArb: Arbitrary[Int], intAArb : Arbitrary[Int => A]): Arbitrary[Test2[A]] = Arbitrary(for {s <- seqArb.arbitrary; f <- intAArb.arbitrary} yield Test2(s, f)) - object Test1Interpreter extends NaturalTransformation[Test1Algebra,Id] { + object Test1Interpreter extends FunctionK[Test1Algebra,Id] { override def apply[A](fa: Test1Algebra[A]): Id[A] = fa match { case Test1(k, h) => h(k) } } - object Test2Interpreter extends NaturalTransformation[Test2Algebra,Id] { + object Test2Interpreter extends FunctionK[Test2Algebra,Id] { override def apply[A](fa: Test2Algebra[A]): Id[A] = fa match { case Test2(k, h) => h(k) } } - val coProductInterpreter: NaturalTransformation[T,Id] = Test1Interpreter or Test2Interpreter + val coProductInterpreter: FunctionK[T,Id] = Test1Interpreter or Test2Interpreter val x: Free[T, Int] = Free.inject[Test1Algebra, T](Test1(1, identity)) diff --git a/tests/src/test/scala/cats/tests/NaturalTransformationTests.scala b/tests/src/test/scala/cats/tests/FunctionKTests.scala similarity index 77% rename from tests/src/test/scala/cats/tests/NaturalTransformationTests.scala rename to tests/src/test/scala/cats/tests/FunctionKTests.scala index 3c69bc8a577..15682de62a0 100644 --- a/tests/src/test/scala/cats/tests/NaturalTransformationTests.scala +++ b/tests/src/test/scala/cats/tests/FunctionKTests.scala @@ -1,18 +1,18 @@ package cats package tests -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.data.Coproduct -class NaturalTransformationTests extends CatsSuite { +class FunctionKTests extends CatsSuite { val listToOption = - new NaturalTransformation[List, Option] { + new FunctionK[List, Option] { def apply[A](fa: List[A]): Option[A] = fa.headOption } val optionToList = - new NaturalTransformation[Option, List] { + new FunctionK[Option, List] { def apply[A](fa: Option[A]): List[A] = fa.toList } @@ -28,11 +28,11 @@ class NaturalTransformationTests extends CatsSuite { case class Test2[A](v : A) extends Test2Algebra[A] - object Test1NT extends NaturalTransformation[Test1Algebra,Id] { + object Test1NT extends FunctionK[Test1Algebra,Id] { override def apply[A](fa: Test1Algebra[A]): Id[A] = fa.v } - object Test2NT extends NaturalTransformation[Test2Algebra,Id] { + object Test2NT extends FunctionK[Test2Algebra,Id] { override def apply[A](fa: Test2Algebra[A]): Id[A] = fa.v } @@ -54,7 +54,7 @@ class NaturalTransformationTests extends CatsSuite { test("id is identity") { forAll { (list: List[Int]) => - NaturalTransformation.id[List].apply(list) should === (list) + FunctionK.id[List].apply(list) should === (list) } } diff --git a/tests/src/test/scala/cats/tests/KleisliTests.scala b/tests/src/test/scala/cats/tests/KleisliTests.scala index bcfd7f1ba54..1b831986b5c 100644 --- a/tests/src/test/scala/cats/tests/KleisliTests.scala +++ b/tests/src/test/scala/cats/tests/KleisliTests.scala @@ -1,7 +1,7 @@ package cats package tests -import cats.arrow.{Arrow, Choice, Split, NaturalTransformation} +import cats.arrow.{Arrow, Choice, Split, FunctionK} import cats.data.{XorT, Kleisli, Reader} import cats.functor.{Contravariant, Strong} import cats.laws.discipline._ @@ -126,7 +126,7 @@ class KleisliTests extends CatsSuite { test("transform") { val opt = Kleisli { (x: Int) => Option(x.toDouble) } - val optToList = new NaturalTransformation[Option,List] { def apply[A](fa: Option[A]): List[A] = fa.toList } + val optToList = new FunctionK[Option,List] { def apply[A](fa: Option[A]): List[A] = fa.toList } val list = opt.transform(optToList) val is = 0.to(10).toList