> {-# LANGUAGE RankNTypes #-}
I was wondering if there was a way to represent the axiom of choice in haskell and/or some other functional programming language.
As we know, false is represented by the type with no values (Void
in haskell).
> import Data.Void
We can represent negation like so
> type Not a = a -> Void
We can express the law of excluded middle for a type a
like so
> type LEM a = Either a (a -> Void)
This means we can make constructive logic into a Reader
monad
> type Constructive a = (forall r. LEM r) -> a
We can, for example, do double negation elimination in it
> doubleneg :: Constructive (((a -> Void) -> Void) -> a)
> doubleneg = \lem nna -> either id (absurd . nna) lem
We can also have a monad where the law of excluded middle fails
> type AntiConstructive a = ((forall r. LEM r) -> Void) -> a
Now the question is, how can we make a type that represents the axiom of choice? The axiom of choice talks about sets of sets. This implies we would need types of types or something. Is there something equivalent to the axiom of choice that could be encoded? (If you can encode the negation, just combine it with the law of excluded middle). Maybe trickery would allow us to have types of types.
Note: Ideally, it should be a version of the axiom of choice that works with Diaconescu's theorem.