Skip to content

Commit

Permalink
fix: make the NaturalTransformation lazy in order to not duplicate ef…
Browse files Browse the repository at this point in the history
…fects

for Id ~> Action
  • Loading branch information
etorreborre committed Oct 12, 2024
1 parent 3383b3a commit 66c4a21
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 4 deletions.
8 changes: 7 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,13 @@ lazy val mimaSettings =
// Because, in that case, it is very possible to confuse the ownEnv with the env and shutdown the env
// which breaks the execution of the whole specification
ProblemFilters.exclude[DirectMissingMethodProblem]("org.specs2.specification.core.OwnEnv.ownEnv"),
ProblemFilters.exclude[DirectMissingMethodProblem]("org.specs2.specification.core.OwnExecutionEnv.env")
ProblemFilters.exclude[DirectMissingMethodProblem]("org.specs2.specification.core.OwnExecutionEnv.env"),

// issue #1277 NaturalTransformation needs to be made lazier
ProblemFilters.exclude[IncompatibleMethTypeProblem]("org.specs2.fp.NaturalTransformation.apply"),
ProblemFilters.exclude[ReversedMissingMethodProblem]("org.specs2.fp.NaturalTransformation.apply"),
ProblemFilters.exclude[IncompatibleMethTypeProblem]("org.specs2.fp.NaturalTransformation#naturalId.apply"),
ProblemFilters.exclude[IncompatibleMethTypeProblem]("org.specs2.control.Operation#operationToAction.apply")
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ object Operation:
"Applicative[Operation]"

given operationToAction: NaturalTransformation[Operation, Action] with
def apply[A](operation: Operation[A]): Action[A] =
def apply[A](operation: =>Operation[A]): Action[A] =
operation.toAction

given SafeOperation: Safe[Operation] with
Expand Down
27 changes: 27 additions & 0 deletions core/jvm/src/test/scala/org/specs2/fp/FoldSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package user

import org.specs2.*
import org.specs2.concurrent.*
import org.specs2.control.*
import org.specs2.control.origami.*
import org.specs2.control.producer.*
import org.specs2.fp.*

class FoldSpec(ee: ExecutionEnv) extends Specification {
def is = s2"""

A correct implementation of NaturalTransformation from Id to Action must not duplicate effects (see issue #1277) $dontDuplicateEffects

"""

def dontDuplicateEffects = {
val p = Producer.emitAll[Action, Int](1, 2, 3)

// The NaturalTransformation from Id (which is Id[X] X) to Action must
// make sure to not run side effects of X twice.
// This tests guarantees that during the evaluation of `zip` and the various folds
// we don't run the action for collection elements into a mutable map more than necessary.
val vs = p.fold(Folds.list[Int].into[Action] `zip` Folds.list[Int].into[Action])
vs.run(ee) === (List(1, 2, 3), List(1, 2, 3))
}
}
4 changes: 2 additions & 2 deletions fp/src/main/scala/org/specs2/fp/NaturalTransformation.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package org.specs2.fp

trait NaturalTransformation[-F[_], +G[_]]:
def apply[A](fa: F[A]): G[A]
def apply[A](fa: =>F[A]): G[A]

object NaturalTransformation:

given naturalId[M[_]: Monad]: NaturalTransformation[Id, M] with
def apply[A](fa: Id[A]): M[A] =
def apply[A](fa: =>Id[A]): M[A] =
summon[Monad[M]].point(fa)

0 comments on commit 66c4a21

Please sign in to comment.