zio-prelude icon indicating copy to clipboard operation
zio-prelude copied to clipboard

Consider deriving `IdentityBoth` from `Covariant` and `IdentityFlatten`

Open felher opened this issue 4 years ago • 0 comments

Currently, when a function requires IdentityBoth on some F[+_] but only Covariant as well as IdentityFlatten are in scope, the compilation fails with an implicit not found.

Should zio-prelude provide automatic derivation for IdentityBoth given Covariant as well as IdentityFlatten? The process could be as follows:

  1. move every IdentityBoth instance of every data type already providing one to the companion object of AssociativeBoth
  2. create a new trait containing something like
sealed trait LowerOrderImplicit {
  implicit def derive[F[+_]](implicit
    C: Covariant[F],
    IF: IdentityFlatten[F]
  ): IdentityBoth[F] =
    new IdentityBoth[F] {
      def any = IF.any

      override def both[A, B](fa: => F[A], fb: => F[B]): F[(A, B)] =
        IF.flatten(C.map((a: A) => C.map((b: B) => (a, b))(fb))(fa))
    }
}
  1. make the companion object inherit from that trait.

I tried to do it, but I failed pretty early, because after moving NonEmptyListInstanceBoth, I got

[error] /home/felher/sources/ref/zio-prelude/src/test/scala/zio/prelude/NonEmptyListSpec.scala:46:63: could not find implicit value for evidence parameter of type zio.prelude.coherent.AssociativeBothDeriveEqualInvariant[[+A]zio.prelude.NonEmptyList[A]]
[error]         testM("associativeBoth")(checkAllLaws(AssociativeBoth)(GenFs.nonEmptyList, Gen.anyInt)),

and I did not have the time to dig deeper. This happened even before defining the LowerOrderImplicit trait, FWIW.

It think in theory this approach should work for data types in prelude. But after @sideeffffect noted that this might lead to ambiguous implicits, I'm not completely sure what to do if users want to define instances for their own datatype. Since they cant define their specialized instances on the companion object, they might either have to stick with the derived one, or would have to do manual imports. Otherwise they will see ambiguous implicit.

felher avatar Oct 14 '20 20:10 felher