cats icon indicating copy to clipboard operation
cats copied to clipboard

Bifoldable Laws with non-commutative types

Open bpholt opened this issue 3 years ago • 0 comments

I noticed that the existing bifoldable laws for Binested fail if you use Tuple2 instead of Either as the two-slot type constructor, and a non-commutative monoid for the innermost types. e.g. adding

checkAll(
  "Binested[Tuple2, ListWrapper, ListWrapper, *, *]",
  BitraverseTests[Binested[Tuple2, ListWrapper, ListWrapper, *, *]]
    .bitraverse[Option, Int, Int, String, String, String, String]
)

fails cats.tests.BinestedSuite.Binested[Tuple2, ListWrapper, ListWrapper, *, *]: bitraverse.bifoldRight consistent with bifoldMap, vs the existing one, which passes:

https://github.com/typelevel/cats/blob/b036fb47196d1a788db09eb2bc262071fa3cb928/tests/shared/src/test/scala/cats/tests/BinestedSuite.scala#L86-L90

Assuming the implementation is correct and the failure hasn't revealed a bug, it makes me wonder if there's a way to encode this in the types. Should the C: Monoid on BitraverseTests.bitraverse be C: CommutativeMonoid so that the law is more universal? If so, how far up the chain should that propagate? Ultimately it's used in BifoldableLaws.bifoldLeftConsistentWithBifoldMap and BifoldableLaws.bifoldRightConsistentWithBifoldMap.

bpholt avatar Dec 29 '22 18:12 bpholt