From 8639d37e6d047ac49d4d02075b3e02f80a512234 Mon Sep 17 00:00:00 2001 From: Denis Rosca Date: Mon, 25 Mar 2019 14:27:20 +0000 Subject: [PATCH] Make MonoidK[Endo] stack safe on combineK --- core/src/main/scala/cats/instances/function.scala | 12 ++++++++++-- tests/src/test/scala/cats/tests/FunctionSuite.scala | 8 ++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/cats/instances/function.scala b/core/src/main/scala/cats/instances/function.scala index b5ba248e79..9e772d7264 100644 --- a/core/src/main/scala/cats/instances/function.scala +++ b/core/src/main/scala/cats/instances/function.scala @@ -3,6 +3,7 @@ package instances import cats.Contravariant import cats.arrow.{ArrowChoice, Category, CommutativeArrow} +import cats.data.AndThen import annotation.tailrec @@ -151,8 +152,15 @@ sealed private[instances] trait Function1Instances extends Function1Instances0 { def compose[A, B, C](f: B => C, g: A => B): A => C = f.compose(g) } - implicit val catsStdMonoidKForFunction1: MonoidK[Endo] = - Category[Function1].algebraK + implicit val catsStdMonoidKForFunction1: MonoidK[Endo] = new MonoidK[Endo] { + + val category: Category[Function] = Category[Function1] + + override def empty[A]: Endo[A] = category.id + + override def combineK[A](x: Endo[A], y: Endo[A]): Endo[A] = + AndThen(category.compose(x, y)) + } } diff --git a/tests/src/test/scala/cats/tests/FunctionSuite.scala b/tests/src/test/scala/cats/tests/FunctionSuite.scala index 1b56ca44a8..c1167cab94 100644 --- a/tests/src/test/scala/cats/tests/FunctionSuite.scala +++ b/tests/src/test/scala/cats/tests/FunctionSuite.scala @@ -138,4 +138,12 @@ class FunctionSuite extends CatsSuite { checkAll("CommutativeGroup[String => CGrp]", SerializableTests.serializable(CommutativeGroup[String => CGrp])) checkAll("ContravariantMonoidal[Function1[?, Monoid]]", SerializableTests.serializable(ContravariantMonoidal[? => Long])) + + test("MonoidK[Endo] is stack safe on combineK") { + def incrementAll(as: Int): Int = as + 1 + val bigList: List[Int => Int] = List.fill(50000)(incrementAll) + + val sumAll = bigList.combineAll(MonoidK[Endo].algebra) + List(1, 1, 1).map(sumAll) + } }