matt-noonan / gdp

Ghosts of Departed Proofs
BSD 3-Clause "New" or "Revised" License
60 stars 11 forks source link

Refactor logic #3

Closed endgame closed 6 years ago

endgame commented 6 years ago

Sorry this took so long. It got a bit bigger than I intended. I'm happy to split it into smaller PRs if there are bits you don't want, or want to take in smaller chunks.

Summary of changes:

Other remarks:

Closes #2.

matt-noonan commented 6 years ago

This looks great, thank you!

My only request is to restore the default signatures for the algebraic property typeclasses, except using your all-Proof types. This lets the library author write empty instance declarations for the symbols they create, while forcing anybody else to write explicit instances. It doesn't make a huge difference, but I do think it is better to make it marginally harder for the library user to declare properties, relative to the library author. Ideally, if the user wants to make an instance for one of these properties, they would provide an actual proof instead of axiom. Does that seem reasonable to you, too?

endgame commented 6 years ago

Do you mean something like this?

class Transitive c where
  transitive :: Proof (c p q) -> Proof (c q r) -> Proof (c p r)
  default transitive :: Defining (c p q) => Proof (c p q) -> Proof (c q r) -> Proof (c p r)
  transitive _ _ = axiom

I'm not a huge fan but if you really want it I'll put it in. Reasoning:

  1. If you're not defining a property alongside your connective, you're creating an orphan instance which is already Frowned Upon.
  2. It forces the programmer to define constructors that never get used, just to make the default rule fire. This seems a bit subtle.

The best practice against orphan instances already gets you the protection you want: you assert these properties either against known connectives when you define the class, or against known classes when you define new connectives.

matt-noonan commented 6 years ago

Fair enough!