| 1 | {-# LANGUAGE UnicodeSyntax #-} |
|---|
| 2 | {-# LANGUAGE DeriveDataTypeable #-} |
|---|
| 3 | {-# LANGUAGE EmptyDataDecls #-} |
|---|
| 4 | {-# LANGUAGE TypeOperators #-} |
|---|
| 5 | {-# LANGUAGE ScopedTypeVariables #-} |
|---|
| 6 | {-# LANGUAGE Rank2Types #-} |
|---|
| 7 | {-# LANGUAGE GADTs #-} |
|---|
| 8 | {-# LANGUAGE TypeFamilies #-} |
|---|
| 9 | {-# LANGUAGE MultiParamTypeClasses #-} |
|---|
| 10 | {-# LANGUAGE FlexibleContexts #-} |
|---|
| 11 | {-# LANGUAGE FlexibleInstances #-} |
|---|
| 12 | {-# LANGUAGE OverlappingInstances #-} |
|---|
| 13 | {-# LANGUAGE UndecidableInstances #-} |
|---|
| 14 | |
|---|
| 15 | module Main where |
|---|
| 16 | |
|---|
| 17 | import Data.Typeable |
|---|
| 18 | import Control.Exception |
|---|
| 19 | |
|---|
| 20 | data Attempt α = Success α |
|---|
| 21 | | â e . Exception e â Failure e |
|---|
| 22 | |
|---|
| 23 | data Inject f α = â β . Inject (f β) (α â β) |
|---|
| 24 | |
|---|
| 25 | class Completable f where |
|---|
| 26 | complete â· f α â α â IO Bool |
|---|
| 27 | |
|---|
| 28 | instance Completable f â Completable (Inject f) where |
|---|
| 29 | complete (Inject f inj) = complete f . inj |
|---|
| 30 | |
|---|
| 31 | class WaitOp op where |
|---|
| 32 | type WaitOpResult op |
|---|
| 33 | registerWaitOp â· Completable f |
|---|
| 34 | â op â f (Attempt (WaitOpResult op)) â IO Bool |
|---|
| 35 | |
|---|
| 36 | data WaitOps rs where |
|---|
| 37 | WaitOp â· WaitOp op â op â WaitOps (HSingle (WaitOpResult op)) |
|---|
| 38 | (:?) â· (WaitOp op, HNonEmpty rs) |
|---|
| 39 | â op â WaitOps rs â WaitOps (WaitOpResult op :* rs) |
|---|
| 40 | |
|---|
| 41 | waitOpsNonEmpty â· â rs . WaitOps rs â HNonEmptyInst rs |
|---|
| 42 | waitOpsNonEmpty (WaitOp _) = HNonEmptyInst |
|---|
| 43 | waitOpsNonEmpty (_ :? _) = HNonEmptyInst |
|---|
| 44 | |
|---|
| 45 | infixr 7 .? |
|---|
| 46 | infix 8 .?. |
|---|
| 47 | |
|---|
| 48 | (.?) â· WaitOp op â op â WaitOps rs â WaitOps (WaitOpResult op :* rs) |
|---|
| 49 | op .? ops = case waitOpsNonEmpty ops of |
|---|
| 50 | HNonEmptyInst â op :? ops |
|---|
| 51 | |
|---|
| 52 | (.?.) â· (WaitOp op1, WaitOp op2) â op1 â op2 |
|---|
| 53 | â WaitOps (WaitOpResult op1 :*: WaitOpResult op2) |
|---|
| 54 | op1 .?. op2 = op1 .? WaitOp op2 |
|---|
| 55 | |
|---|
| 56 | data NthException n e = NthException (Peano n) e deriving (Typeable, Show) |
|---|
| 57 | |
|---|
| 58 | instance (Typeable n, Exception e) â Exception (NthException n e) |
|---|
| 59 | |
|---|
| 60 | instance WaitOp (WaitOps rs) where |
|---|
| 61 | type WaitOpResult (WaitOps rs) = HElemOf rs |
|---|
| 62 | registerWaitOp ops ev = do |
|---|
| 63 | let register â· â n . HDropClass n rs |
|---|
| 64 | â Bool â Peano n â WaitOps (HDrop n rs) â IO Bool |
|---|
| 65 | register first n (WaitOp op) = do |
|---|
| 66 | let inj n (Success r) = Success (HNth n r) |
|---|
| 67 | inj n (Failure e) = Failure (NthException n e) |
|---|
| 68 | t â try $ registerWaitOp op (Inject ev $ inj n) |
|---|
| 69 | r â case t of |
|---|
| 70 | Right r â return r |
|---|
| 71 | Left e â complete ev $ inj n $ Failure (e â· SomeException) |
|---|
| 72 | return $ r || not first |
|---|
| 73 | register first n (op :? ops') = do |
|---|
| 74 | let inj n (Success r) = Success (HNth n r) |
|---|
| 75 | inj n (Failure e) = Failure (NthException n e) |
|---|
| 76 | t â try $ registerWaitOp op (Inject ev $ inj n) |
|---|
| 77 | case t of |
|---|
| 78 | Right True â case waitOpsNonEmpty ops' of |
|---|
| 79 | HNonEmptyInst â case hTailDropComm â· HTailDropComm n rs of |
|---|
| 80 | HTailDropComm â register False (PSucc n) ops' |
|---|
| 81 | Right False â return $ not first |
|---|
| 82 | Left e â do |
|---|
| 83 | c â complete ev $ inj $ Failure (e â· SomeException) |
|---|
| 84 | return $ c || not first |
|---|
| 85 | case waitOpsNonEmpty ops of |
|---|
| 86 | HNonEmptyInst â register True PZero ops |
|---|
| 87 | |
|---|
| 88 | main = return () |
|---|
| 89 | |
|---|
| 90 | data PZero deriving Typeable |
|---|
| 91 | data PSucc p deriving Typeable |
|---|
| 92 | |
|---|
| 93 | data Peano n where |
|---|
| 94 | PZero â· Peano PZero |
|---|
| 95 | PSucc â· IsPeano p â Peano p â Peano (PSucc p) |
|---|
| 96 | |
|---|
| 97 | instance Show (Peano n) where |
|---|
| 98 | show n = show (peanoNum n â· Int) |
|---|
| 99 | |
|---|
| 100 | peanoNum â· Num n â Peano p â n |
|---|
| 101 | peanoNum PZero = 0 |
|---|
| 102 | peanoNum (PSucc p) = 1 + peanoNum p |
|---|
| 103 | |
|---|
| 104 | class Typeable n â IsPeano n where |
|---|
| 105 | peano â· Peano n |
|---|
| 106 | |
|---|
| 107 | instance IsPeano PZero where |
|---|
| 108 | peano = PZero |
|---|
| 109 | |
|---|
| 110 | instance IsPeano p â IsPeano (PSucc p) where |
|---|
| 111 | peano = PSucc peano |
|---|
| 112 | |
|---|
| 113 | class (n ~ PSucc (PPred n)) â PHasPred n where |
|---|
| 114 | type PPred n |
|---|
| 115 | |
|---|
| 116 | instance PHasPred (PSucc p) where |
|---|
| 117 | type PPred (PSucc p) = p |
|---|
| 118 | |
|---|
| 119 | pPred â· Peano (PSucc p) â Peano p |
|---|
| 120 | pPred (PSucc p) = p |
|---|
| 121 | |
|---|
| 122 | infixr 7 :*, .* |
|---|
| 123 | infix 8 :*:, .*. |
|---|
| 124 | |
|---|
| 125 | data HNil |
|---|
| 126 | data h :* t |
|---|
| 127 | type HSingle α = α :* HNil |
|---|
| 128 | type α :*: β = α :* β :* HNil |
|---|
| 129 | |
|---|
| 130 | data HList l where |
|---|
| 131 | HNil â· HList HNil |
|---|
| 132 | (:*) â· HListClass t â h â HList t â HList (h :* t) |
|---|
| 133 | |
|---|
| 134 | instance Show (HList HNil) where |
|---|
| 135 | show _ = "HNil" |
|---|
| 136 | |
|---|
| 137 | instance (Show h, Show (HList t)) â Show (HList (h :* t)) where |
|---|
| 138 | showsPrec d (h :* t) = showParen (d > 7) $ |
|---|
| 139 | showsPrec 8 h . showString " .* " . showsPrec 7 t |
|---|
| 140 | |
|---|
| 141 | (.*) â· HListClass t â h â HList t â HList (h :* t) |
|---|
| 142 | (.*) = (:*) |
|---|
| 143 | |
|---|
| 144 | (.*.) ⷠα â β â HList (α :*: β) |
|---|
| 145 | a .*. b = a .* b .* HNil |
|---|
| 146 | |
|---|
| 147 | data HListWitness l where |
|---|
| 148 | HNilList â· HListWitness HNil |
|---|
| 149 | HConsList â· HListClass t â HListWitness (h :* t) |
|---|
| 150 | |
|---|
| 151 | class HListClass l where |
|---|
| 152 | hListWitness â· HListWitness l |
|---|
| 153 | |
|---|
| 154 | instance HListClass HNil where |
|---|
| 155 | hListWitness = HNilList |
|---|
| 156 | |
|---|
| 157 | instance HListClass t â HListClass (h :* t) where |
|---|
| 158 | hListWitness = HConsList |
|---|
| 159 | |
|---|
| 160 | data HListInst l where |
|---|
| 161 | HListInst â· HListClass l â HListInst l |
|---|
| 162 | |
|---|
| 163 | hListInst â· HList l â HListInst l |
|---|
| 164 | hListInst HNil = HListInst |
|---|
| 165 | hListInst (_ :* _) = HListInst |
|---|
| 166 | |
|---|
| 167 | class (l ~ (HHead l :* HTail l), HListClass (HTail l)) â HNonEmpty l where |
|---|
| 168 | type HHead l |
|---|
| 169 | type HTail l |
|---|
| 170 | |
|---|
| 171 | instance HListClass t â HNonEmpty (h :* t) where |
|---|
| 172 | type HHead (h :* t) = h |
|---|
| 173 | type HTail (h :* t) = t |
|---|
| 174 | |
|---|
| 175 | hHead â· HList (h :* t) â h |
|---|
| 176 | hHead (h :* _) = h |
|---|
| 177 | |
|---|
| 178 | hTail â· HList (h :* t) â HList t |
|---|
| 179 | hTail (_ :* t) = t |
|---|
| 180 | |
|---|
| 181 | data HNonEmptyInst l where |
|---|
| 182 | HNonEmptyInst â· HListClass t â HNonEmptyInst (h :* t) |
|---|
| 183 | |
|---|
| 184 | data HDropWitness n l where |
|---|
| 185 | HDropZero â· HListClass l â HDropWitness PZero l |
|---|
| 186 | HDropSucc â· HDropClass p t â HDropWitness (PSucc p) (h :* t) |
|---|
| 187 | |
|---|
| 188 | class (IsPeano n, HListClass l, HListClass (HDrop n l)) â HDropClass n l where |
|---|
| 189 | type HDrop n l |
|---|
| 190 | hDropWitness â· HDropWitness n l |
|---|
| 191 | |
|---|
| 192 | instance HListClass l â HDropClass PZero l where |
|---|
| 193 | type HDrop PZero l = l |
|---|
| 194 | hDropWitness = HDropZero |
|---|
| 195 | |
|---|
| 196 | instance HDropClass p t â HDropClass (PSucc p) (h :* t) where |
|---|
| 197 | type HDrop (PSucc p) (h :* t) = HDrop p t |
|---|
| 198 | hDropWitness = case hDropWitness â· HDropWitness p t of |
|---|
| 199 | HDropZero â HDropSucc |
|---|
| 200 | HDropSucc â HDropSucc |
|---|
| 201 | |
|---|
| 202 | data HDropInst n l where |
|---|
| 203 | HDropInst â· HDropClass n l â HDropInst n l |
|---|
| 204 | |
|---|
| 205 | hDrop â· â n l . HDropClass n l â Peano n â HList l â HList (HDrop n l) |
|---|
| 206 | hDrop n l = case hDropWitness â· HDropWitness n l of |
|---|
| 207 | HDropZero â l |
|---|
| 208 | HDropSucc â hDrop (pPred n) (hTail l) |
|---|
| 209 | |
|---|
| 210 | data HNonEmptyDropInst n l where |
|---|
| 211 | HNonEmptyDropInst â· (HDropClass n l, HNonEmpty l, |
|---|
| 212 | HDropClass (PSucc n) l, HNonEmpty (HDrop n l)) |
|---|
| 213 | â HNonEmptyDropInst n l |
|---|
| 214 | |
|---|
| 215 | pPrevDropInst â· â n l . HDropClass (PSucc n) l â HNonEmptyDropInst n l |
|---|
| 216 | pPrevDropInst = case hDropWitness â· HDropWitness (PSucc n) l of |
|---|
| 217 | HDropSucc â case hDropWitness â· HDropWitness n (HTail l) of |
|---|
| 218 | HDropZero â HNonEmptyDropInst |
|---|
| 219 | HDropSucc â case pPrevDropInst â· HNonEmptyDropInst (PPred n) (HTail l) of |
|---|
| 220 | HNonEmptyDropInst â HNonEmptyDropInst |
|---|
| 221 | |
|---|
| 222 | hNextDropInst â· â n l . (HDropClass n l, HNonEmpty (HDrop n l)) |
|---|
| 223 | â HNonEmptyDropInst n l |
|---|
| 224 | hNextDropInst = case hDropWitness â· HDropWitness n l of |
|---|
| 225 | HDropZero â HNonEmptyDropInst |
|---|
| 226 | HDropSucc â case hNextDropInst â· HNonEmptyDropInst (PPred n) (HTail l) of |
|---|
| 227 | HNonEmptyDropInst â HNonEmptyDropInst |
|---|
| 228 | |
|---|
| 229 | data HTailDropComm n l where |
|---|
| 230 | HTailDropComm â· (HNonEmpty l, HDropClass n l, |
|---|
| 231 | HNonEmpty (HDrop n l), HDropClass n (HTail l), |
|---|
| 232 | HDropClass (PSucc n) l, |
|---|
| 233 | HTail (HDrop n l) ~ HDrop n (HTail l), |
|---|
| 234 | HDrop (PSucc n) l ~ HTail (HDrop n l), |
|---|
| 235 | HDrop (PSucc n) l ~ HDrop n (HTail l)) |
|---|
| 236 | â HTailDropComm n l |
|---|
| 237 | |
|---|
| 238 | hTailDropComm' â· â n l . (HDropClass (PSucc n) l) |
|---|
| 239 | â HTailDropComm n l |
|---|
| 240 | hTailDropComm' = case pPrevDropInst â· HNonEmptyDropInst n l of |
|---|
| 241 | HNonEmptyDropInst â hTailDropComm |
|---|
| 242 | |
|---|
| 243 | hTailDropComm â· â n l . (HDropClass n l, HNonEmpty (HDrop n l)) |
|---|
| 244 | â HTailDropComm n l |
|---|
| 245 | hTailDropComm = case hDropWitness â· HDropWitness n l of |
|---|
| 246 | HDropZero â HTailDropComm |
|---|
| 247 | HDropSucc â case hTailDropComm â· HTailDropComm (PPred n) (HTail l) of |
|---|
| 248 | HTailDropComm â HTailDropComm |
|---|
| 249 | |
|---|
| 250 | type HNth n l = HHead (HDrop n l) |
|---|
| 251 | |
|---|
| 252 | data HElemOf l where |
|---|
| 253 | HNth â· (HDropClass n l, HNonEmpty (HDrop n l)) |
|---|
| 254 | â Peano n â HNth n l â HElemOf l |
|---|