frees-io / iota

Fast [co]product types with a clean syntax. For Cats & Scalaz.
Apache License 2.0
176 stars 22 forks source link

Utilities, Prod/Cop features, and Macros #247

Closed fommil closed 5 years ago

fommil commented 5 years ago

I have a bunch of stuff in scalaz-deriving that you're more than welcome to take here under whatever license you want

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

Other than the boilerplate helpers, the more funky stuff gives me a blackbox (not whitebox) macro to generate the equivalent of shapeless' LabelledGeneric and ways to map, traverse, and other weird combinators on Prod and Cop where there is some evidence relating them.

It's probably all a hack job. But it seems to work. And you're welcome to it if you want it, butI don't have time to raise a PR.

fommil commented 5 years ago

For the macros, make sure to look no later than 1.0.0-RC6 as I'm removing support for field / coproduct labels, just using IsoSet

https://gitlab.com/fommil/scalaz-deriving/tree/v1.0.0-RC6/scalaz-deriving/src/main/scala/iotaz

andyscott commented 5 years ago

Sounds good. Thanks @fommil!

fommil commented 5 years ago

I just added this code to scalaz-deriving, that is relevant

      // this could be optimised if there was a way to create an immutable.Seq
      // from a Product, but alas there is only an Iterator. A custom impl may
      // be needed.
      val cons =
        if (aSym.isCaseClass)
          q"(a: $A) => ${Prod.companion}.unsafeApply[$R](a.productIterator.toList)"
        else q"(a: $A) => ${Prod.companion}[$R](..$fromParts)"
fommil commented 5 years ago

I now have an optimised ProductSeq to wrap a case class as a Seq... but I noticed that your Prod constructor is using Vector by default and that kind of sucks for performance.

fommil commented 5 years ago

expect a PR...