algebra icon indicating copy to clipboard operation
algebra copied to clipboard

Add byAll and fromAll to Eq/PartialOrder/Order

Open non opened this issue 8 years ago • 3 comments

Something that I've received requests for is an easier way to define these instances.

Here's an example of what I mean (assume we can't automatically derive instances for case classes/products):

case class Foo(a: Int, b: String, c: Int)

// a function is used if the previous function returned 0/EQ
val o1: Order[Foo] = Order.fromAll[Foo](
  (x, y) => x.a compare y.a,
  (x, y) => x.b compare y.b,
  (x, y) => x.c compare y.c)

// here's an even more terse version that will use Order[Int] and Order[String]
val o2: Order[Foo] = Order.byAll(_.a, _.b, _.c)

The logic in both cases is that the first function is used -- and if the items are equal, the next one is used, otherwise the result returns immediately. If after the last function runs they are equal, then 0/EQ is returned.

non avatar Jul 07 '15 20:07 non

we've been making macros for these cases. I assume the macros offer better performance, but maybe I'm wrong. Certainly better usability.

I can see adding these "generalization over case class" instances being something we have standard macros for in many of our cases: Semigroup, Monoid, Group, Ring (but not Field), Order, Eq, PartialOrder, and probably more.

johnynek avatar Jul 07 '15 20:07 johnynek

I would be happy to use macros. I agree that the performance will be much better when function literals are used (they can be inlined into the code you would explicitly write, more-or-less).

non avatar Jul 07 '15 20:07 non

I bet if we are careful, we can get a lot of code reuse between the different typeclasses over case-classes.

johnynek avatar Jul 07 '15 20:07 johnynek