Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deriving typeclass instances for CopK #218

Open
lukaszwawrzyk opened this issue May 16, 2018 · 4 comments
Open

Deriving typeclass instances for CopK #218

lukaszwawrzyk opened this issue May 16, 2018 · 4 comments

Comments

@lukaszwawrzyk
Copy link
Contributor

lukaszwawrzyk commented May 16, 2018

@andyscott
Hi!
I am working on migration of quasar from scalaz.Coproduct to iotaz.CopK. We need a way to create instances of arbitrary typeclasses for arbitrary CopKs.

It seems like there is no way to do this with iota currently. Did you think about that? Do you know how could it be solved? Any suggestions are welcome. I am happy to submit a PR. We will be working on that anyway, but any guidelines would be appriciated.

The only solution that comes to my mind that would surely work but is far far far from ideal is to create a separate macro for each coproduct.

To give some example of what needs to be migrated:

  implicit def coproductEqual[F[_], G[_]](implicit F: Delay[Equal, F], G: Delay[Equal, G]): Delay[Equal, Coproduct[F, G, ?]] =
    Delay.fromNT(λ[Equal ~> Equal[Coproduct[F, G, ?]](eq =>
      Equal equal ((cp1, cp2) =>
        (cp1.run, cp2.run) match {
          case (-\/(f1), -\/(f2)) => F(eq).equal(f1, f2)
          case (\/-(g1), \/-(g2)) => G(eq).equal(g1, g2)
          case (_,       _)       => false
        })))
  implicit def coproduct[M[_], FMT, F[_], G[_], J](
    implicit F: Lazy[Planner[M, FMT, F, J]], G: Lazy[Planner[M, FMT, G, J]]
  ): Planner[M, FMT, Coproduct[F, G, ?], J] =
    new Planner[M, FMT, Coproduct[F, G, ?], J] {
      def plan[Q](
        implicit Q: Birecursive.Aux[Q, Query[J, ?]]
      ): AlgebraM[M, Coproduct[F, G, ?], Search[Q] \/ XQuery] =
        _.run.fold(F.value.plan, G.value.plan)
    }
  implicit def coproduct[T[_[_]], F[_], G[_], H[_]]
    (implicit F: DiscoverPath.Aux[T, F, H], G: DiscoverPath.Aux[T, G, H])
      : DiscoverPath.Aux[T, Coproduct[F, G, ?], H] =
    new DiscoverPath[Coproduct[F, G, ?]] {
      type IT[F[_]] = T[F]
      type OUT[A] = H[A]

      def discoverPath[M[_]: Monad: MonadFsErr](g: ListContents[M]) =
        _.run.fold(F.discoverPath(g), G.discoverPath(g))
    }
@lukaszwawrzyk
Copy link
Contributor Author

https://github.com/djspiewak/iota-instances Here is our current working implementation. Though I must admin it is rather hacky.

@andyscott
Copy link
Member

This has definitely been on my radar to implement but I never had any immediate need for it (and thus never prioritized working on it).

I can revisit this in a few days and potentially provide some ideas and notes. This week I'm busy with extra meetings while I'm on site in SF for work.

Also, @fommil might also have some suggestions on this front ;).

@fommil
Copy link
Contributor

fommil commented May 17, 2018

yeah, I've been doing a bunch of stuff in this area

https://gitlab.com/fommil/scalaz-deriving/tree/master/scalaz-deriving/src/main/scala/iotaz

I'm trying to stick to blackbox macros.

I plan on contributing this back to iotaz over the next few months.

@fommil
Copy link
Contributor

fommil commented May 17, 2018

umm, oh you want to create instances like that. That's a very long winded way of doing it. Try the scalaz-deriving README instead. I have a much better abstraction than that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants