typelevel / algebra

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

Add subprojects; first pass at adding laws and tests. #14

Closed non closed 9 years ago

non commented 9 years ago

This commit creates three sub-projects:

It also ports over the basic laws from Spire for:

Finally, it adds a very simple standard algebra instance for Int, and runs the relevant laws tests on it.

non commented 9 years ago

This would resolve (or at least works towards resolving) #10.

non commented 9 years ago

Also, I'd love for @tixxit and @larsrh to review this. I based this all on Spire's laws but I did some updating. In particular I created functions in Rules.scala that allow me to avoid duplicating definitions for things like associativity, commutativity, distributivity, and so on.

I think it's pretty elegant but it does add some indirection. What do you all think?

Also, @johnynek and @avibryant, do these ScalaCheck/Discipline tests make sense to you all? It's pretty expressive and allows "inheriting" properties, but there is definitely a bit of a learning curve.

non commented 9 years ago

Oh also, one additional comment:

In Spire we use Eq[A] (and the associated infix operators === and =!=) for all equality checks.

Since this project consciously avoids adding infix operators, to keep the tests readable I converted all these checks to == and != :cry:. However, the tests still require an Eq[A] instance so that in the future we can convert back if we want (and also to ensure that we believe equality is sensible for the given type).

avibryant commented 9 years ago

Yep, the laws absolutely make sense.

non commented 9 years ago

From the last commit:

This commit does a few things:

 1. Restores clobbered project/build.scala file.
 2. Add ?-prefixed ScalaCheck operators for better test output
 3. Improves the laws a bit
 4. Adds many std instances, and checks the laws against them
 5. Implements toy rational type ("Rat"); tests the field laws.

At this point I feel like the laws are in good enough shape for
others to start building on. We can also add more std instances.

For now, I am trying to keep the std instances as simple as
possible. This means no specialization, and also no performance
concerns. I don't think we should plan to port over "real" types
to std, but rather use it to check laws and provide simple code.
non commented 9 years ago

So, after realizing we weren't testing the IsReal[A] methods with any laws, I added some laws and of course immediately found a bug in Rat. That'll teach me not to write laws.

At this point all the type classes have laws except NRoot[A]. I will add some laws now, until we add a type like spire.math.Algebraic or spire.math.Real I fear we won't have any types that can actually pass all the tests (e.g. x.pow(3).nroot(3) = x.nroot(3).pow(3) = x).

non commented 9 years ago

I sort of went crazy and started implementing a symbolic type to allow law-checking of things like x.nroot(k).pow(k) = x.pow(k).nroot(k) = x. Ultimately this seemed like a bad thing to ship in algebra.std so I spun it out to its own project.

non commented 9 years ago

I just pushed some commits which (I think) should address all the issues we've seen so far.

Please let me know if there's anything else you think is needed.

non commented 9 years ago

(Also, I think I need to update this PR now that lattices are merged. I'll do that right now.)

non commented 9 years ago

Alright, so the last four commits update this PR to be lattice-aware.

It also adds the three files of laws relating to lattices (LatticeLaws.scala, LogicLaws.scala, and LatticePartialOrderLaws.scala).

non commented 9 years ago

So I went ahead and removed the dependencies from algebra-std as I proposed earlier. Let me know what you all think.

non commented 9 years ago

Most recent commits merge the support for commutativity to this branch, and update the laws accordingly.

The nice thing is that the previous PR couldn't have tests -- but in this branch we were able to confirm that all the instances we had defined were in fact commutative! :fireworks:

tixxit commented 9 years ago

:+1:

non commented 9 years ago

What do you think @johnynek? Anything else you'd like to see done on this PR?