Using Ring Typeclass to Support + and *?

8 views
Skip to first unread message

Kevin Meredith

unread,
Apr 28, 2015, 11:20:10 AM4/28/15
to spire...@googlegroups.com
In working on this cooperative equality issue, I've written a method of signature: List[org.scalacheck.Prop].

The intention of this method is to generically produce a list of properties for an A that supports addition and multiplication.

  def coopEquals[A](x: A, y: A): Boolean = x == y && x.hashCode == y.hashCode

  def props[A : Ring](g: Gen[A]): List[Prop] = {
    val commutativeAdd = forAll(g, g) { (a: A, b: A) =>
      coopEquals(a+b,b+a) 
    }
    val commutativeMult = forAll(g, g) { (a: A, b: A) =>
      coopEquals(a*b,b*a) 
    }
    val transitive = forAll(g, g, g) { (a: A, b: A, c: A) =>
      if( coopEquals(a, b) && coopEquals(b, c)) coopEquals(a, c) else true
    }
    List(coopEqProp(g), commutativeAdd, commutativeMult, transitive)
  }

  def coopEqProp[A](g: Gen[A]): Prop =            // looking at this again, it might be a meaningless property
    forAll(g) { (a: A) => coopEquals(a, a) }

I read over Ring's and Rig's README's, but I'm not entirely clear that using the `Ring` typeclass is appropriate here. Is it?

Thanks.

Erik Osheim

unread,
Apr 28, 2015, 11:27:52 AM4/28/15
to Kevin Meredith, spire...@googlegroups.com
Hi Kevin,

On Tue, Apr 28, 2015 at 08:20:10AM -0700, Kevin Meredith wrote:
> I read over Ring's and Rig's README's, but I'm not entirely clear that
> using the `Ring` typeclass is appropriate here. Is it?

I think using a type class like Ring is the right idea. Since you only
use * and +, you could loosen the constraint to a Semiring if you
wanted.

However, since your test requires commutativity, it might be better to
use a type class which supports commutative multiplication. Currently
we don't have a commutative Semiring, but we do have CRig and CRing. I
think either of those would be a fine choice.

Alternately, you could just use Semiring and just document that you
require commutative *. Or you could even add a CSemiring type class.

Regardless, I think you have the right approach here -- it's a matter
of zeroing in on which type class you want to use.

-- Erik
Reply all
Reply to author
Forward
0 new messages