Bifoldable Laws with non-commutative types
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.