typelevel / algebra

Experimental project to lay out basic algebra type classes
https://typelevel.org/algebra/
Other
378 stars 69 forks source link

Add byAll and fromAll to Eq/PartialOrder/Order #69

Open non opened 9 years ago

non commented 9 years ago

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.

johnynek commented 9 years ago

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.

non commented 9 years ago

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).

johnynek commented 9 years ago

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