|
| 1 | +{- cabal: |
| 2 | +build-depends: base, constraints |
| 3 | +-} |
| 4 | +{-# language TypeFamilies, TypeFamilyDependencies, ConstraintKinds, ScopedTypeVariables, NoStarIsType, TypeOperators, TypeApplications, GADTs, AllowAmbiguousTypes, FunctionalDependencies, UndecidableSuperClasses, UndecidableInstances, FlexibleInstances, QuantifiedConstraints, BlockArguments, RankNTypes, FlexibleContexts, StandaloneKindSignatures, DefaultSignatures #-} |
| 5 | + |
| 6 | + -- ⊷, ≕, =∘, =◯ These choices all look like something out of Star Trek, so let's boldly go... |
| 7 | + |
| 8 | +import Data.Constraint hiding (top, bottom, Bottom) |
| 9 | +import Data.Kind |
| 10 | +import Data.Some |
| 11 | +import Data.Void |
| 12 | +import Unsafe.Coerce |
| 13 | + |
| 14 | +class (Not p ~ Never p) => Never p where |
| 15 | + never :: p => Dict r |
| 16 | + |
| 17 | +class (Prop (Not p), Not (Not p) ~ p) => Prop (p :: Constraint) where |
| 18 | + type Not p :: Constraint |
| 19 | + type Not p = Never p |
| 20 | + |
| 21 | + contradiction :: (p, Not p) => Dict r |
| 22 | + default contradiction :: (Not p ~ Never p, p, Not p) => Dict r |
| 23 | + contradiction = never @p |
| 24 | + |
| 25 | +instance (Prop p, Not p ~ Never p) => Prop (Never p) where |
| 26 | + type Not (Never p) = p |
| 27 | + contradiction = never @p |
| 28 | + |
| 29 | +instance Prop (Bounded a) |
| 30 | +instance Prop (Num a) |
| 31 | + |
| 32 | +instance Never (Bounded Void) where never = absurd minBound |
| 33 | +instance Never (Num Void) where never = absurd (fromInteger 0) |
| 34 | + |
| 35 | +class (p, q) => p * q |
| 36 | +instance (p, q) => p * q |
| 37 | + |
| 38 | +class (Not p => q, Not q => p) => p ⅋ q |
| 39 | +instance (Not p => q, Not q => p) => p ⅋ q |
| 40 | + |
| 41 | +instance (Prop p, Prop q) => Prop (p ⅋ q) where |
| 42 | + type Not (p ⅋ q) = Not p * Not q |
| 43 | + contradiction = contradiction @p |
| 44 | + |
| 45 | +instance (Prop p, Prop q) => Prop (p * q) where |
| 46 | + type Not (p * q) = Not p ⅋ Not q |
| 47 | + contradiction = contradiction @p |
| 48 | + |
| 49 | +infixr 0 ⊸ |
| 50 | +type (⊸) p = (⅋) (Not p) |
| 51 | + |
| 52 | +fun :: (Prop p, Prop q, p) => (p ⊸ q) :- q |
| 53 | +fun = Sub Dict |
| 54 | + |
| 55 | +contra :: (Prop p, Prop q, Not q) => (p ⊸ q) :- Not p |
| 56 | +contra = Sub Dict |
| 57 | + |
| 58 | +class (p, q) => p & q |
| 59 | +instance (p, q) => p & q |
| 60 | + |
| 61 | +class p + q where |
| 62 | + runEither :: (p => Dict r) -> (q => Dict r) -> Dict r |
| 63 | + |
| 64 | +data G p q k = G ((forall r. (p => Dict r) -> (q => Dict r) -> Dict r)) |
| 65 | + |
| 66 | +-- (Eq a + Ord [a]) :- Eq [a] |
| 67 | + |
| 68 | +inl :: forall p q. p :- (p + q) |
| 69 | +inl = Sub let |
| 70 | + go :: (p => Dict r) -> (q => Dict r) -> Dict r |
| 71 | + go pr _ = pr |
| 72 | + in unsafeCoerce (G go) |
| 73 | + |
| 74 | +inr :: forall q p. q :- (p + q) |
| 75 | +inr = Sub let |
| 76 | + go :: (p => Dict r) -> (q => Dict r) -> Dict r |
| 77 | + go _ qr = qr |
| 78 | + in unsafeCoerce (G go) |
| 79 | + |
| 80 | +instance (Prop p, Prop q) => Prop (p & q) where |
| 81 | + type Not (p & q) = Not p + Not q |
| 82 | + contradiction = runEither @(Not p) @(Not q) (contradiction @p) (contradiction @q) |
| 83 | + |
| 84 | +instance (Prop p, Prop q) => Prop (p + q) where |
| 85 | + type Not (p + q) = Not p & Not q |
| 86 | + contradiction = runEither @p @q (contradiction @(Not p)) (contradiction @(Not q)) |
| 87 | + |
| 88 | +withL' :: (p & q) :- p |
| 89 | +withL' = Sub Dict |
| 90 | + |
| 91 | +withR' :: (p & q) :- q |
| 92 | +withR' = Sub Dict |
| 93 | + |
| 94 | +-- now we need to get into more serious dictionary manipulation |
| 95 | + |
| 96 | +-- withL :: Dict (p & q ⊸ p) |
| 97 | +-- withL = Dict |
| 98 | + |
| 99 | + |
| 100 | +type (⊷) :: Constraint -> Constraint -> Type |
| 101 | +data p ⊷ q = Lol (p :- q) (Not q :- Not p) -- should be a with, haskell side |
| 102 | + |
| 103 | +embedLol :: forall p q. (Prop p, Prop q) => (p ⊸ q) => p ⊷ q |
| 104 | +embedLol = Lol (Sub Dict) $ Sub case contra @p @q of |
| 105 | + Sub Dict -> Dict |
| 106 | + |
| 107 | +{- |
| 108 | +
|
| 109 | +class Mk p q where runFun :: p => q |
| 110 | +instance (p => q) => Mk p q where runFun = Dict |
| 111 | +
|
| 112 | +data Box p = Box p |
| 113 | +
|
| 114 | +lift :: (p :- Dict q) => |
| 115 | +lift |
| 116 | + unsafeCoerce (Box (&)) :: Dict (Mk p) |
| 117 | +
|
| 118 | + p -> (p -> r) -> r |
| 119 | +
|
| 120 | +projectLol :: forall p q. (Prop p, Prop q) => (p ⊷ q) -> Dict (p ⊸ q) |
| 121 | +projectLol = error "TODO" |
| 122 | +
|
| 123 | +apply :: forall p q. (p => q) => (p :- q) |
| 124 | +apply = Sub Dict |
| 125 | +-} |
| 126 | + |
| 127 | +{- |
| 128 | +data Box a = Box a |
| 129 | +
|
| 130 | +class Top where |
| 131 | + top :: Some Dict |
| 132 | +
|
| 133 | +mkTop :: a => Dict Top |
| 134 | +mkTop = a => unsafeCoerce (Box (Some (Dict @a)) |
| 135 | +
|
| 136 | +top' :: a :- Top |
| 137 | +top = |
| 138 | +
|
| 139 | +instance Prop Top where |
| 140 | + type Not Top = Zero |
| 141 | +
|
| 142 | +instance Prop () where |
| 143 | + type Not () = Bot |
| 144 | +
|
| 145 | +class Zero where |
| 146 | + zero :: a |
| 147 | +
|
| 148 | +zero :: Dict (Zero ⊸ a) |
| 149 | +zero = Sub Dict |
| 150 | +
|
| 151 | +instance Prop Zero where |
| 152 | + type Not Zero = Top |
| 153 | +
|
| 154 | +class Bot where |
| 155 | + --bot :: (forall r. Top => r) -> |
| 156 | + |
| 157 | +instance Prop Bottom where |
| 158 | + contradiction = _ |
| 159 | +-} |
| 160 | + |
| 161 | +main = return () |
| 162 | + |
0 commit comments