Closed endgame closed 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?
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:
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.
Fair enough!
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:
Proof a
instead ofa
in premises. This makes proof types phantom everywhere.Proof a
, we don't need them.Reflexive
). Because these always take and return proofs, we can make themaxiom
everywhere.Proof
type poly-kinded. So if someone wants to define his or her logic using-XDataKinds
, it's possible to use that in aProof
.Functor/Applicative/Monad
instance and custom operators forProof
, because they don't make logical sense any more.sorry
emit warnings.Functor
/Bifunctor
/Profunctor
.Propositional.hs
tocamelCase
, to make hlint calm down.Other remarks:
Proof (a || b)
andEither (Proof a) (Proof b)
, because you can't tell which ofa
orb
is true, which is how you select which data constructor to use.Functor
/Bifunctor
/Profunctor
instances for the logic types, because to map over a conjunction, say, you need aProof p -> Proof p'
, not ap -> p'
. There might be a typeclass that allows this, but I don't know of one.Closes #2.