|
| 1 | +module Data.DPair |
| 2 | + |
| 3 | +%default total |
| 4 | + |
| 5 | +namespace Exists |
| 6 | + |
| 7 | + ||| A dependent pair in which the first field (witness) should be |
| 8 | + ||| erased at runtime. |
| 9 | + ||| |
| 10 | + ||| We can use `Exists` to construct dependent types in which the |
| 11 | + ||| type-level value is erased at runtime but used at compile time. |
| 12 | + ||| This type-level value could represent, for instance, a value |
| 13 | + ||| required for an intrinsic invariant required as part of the |
| 14 | + ||| dependent type's representation. |
| 15 | + ||| |
| 16 | + ||| @type The type of the type-level value in the proof. |
| 17 | + ||| @this The dependent type that requires an instance of `type`. |
| 18 | + public export |
| 19 | + data Exists : (this : type -> Type) -> Type where |
| 20 | + Evidence : (0 value : type) |
| 21 | + -> (prf : this value) |
| 22 | + -> Exists this |
| 23 | + |
| 24 | + ||| Return the type-level value (evidence) required by the dependent type. |
| 25 | + ||| |
| 26 | + ||| We need to be in the Erased setting for this to work. |
| 27 | + ||| |
| 28 | + ||| @type The type-level value's type. |
| 29 | + ||| @pred The dependent type that requires an instance of `type`. |
| 30 | + ||| @prf That there is a value that satisfies `prf`. |
| 31 | + public export |
| 32 | + 0 |
| 33 | + fst : {0 type : Type} |
| 34 | + -> {0 pred : type -> Type} |
| 35 | + -> (1 prf : Exists pred) |
| 36 | + -> type |
| 37 | + fst (Evidence value _) = value |
| 38 | + |
| 39 | + ||| Return the dependently typed value. |
| 40 | + ||| |
| 41 | + ||| @type The type-level value's type. |
| 42 | + ||| @pred The dependent type that requires an instance of `type`. |
| 43 | + ||| @prf That there is a value that satisfies `prf`. |
| 44 | + public export |
| 45 | + snd : {0 type : Type} |
| 46 | + -> {0 pred : type -> Type} |
| 47 | + -> (1 prf : Exists pred) |
| 48 | + -> pred (Exists.fst prf) |
| 49 | + snd (Evidence value prf) = prf |
| 50 | + |
| 51 | +namespace Subset |
| 52 | + |
| 53 | + ||| A dependent pair in which the second field (evidence) should not |
| 54 | + ||| be required at runtime. |
| 55 | + ||| |
| 56 | + ||| We can use `Subset` to provide extrinsic invariants about a |
| 57 | + ||| value and know that these invariants are erased at |
| 58 | + ||| runtime but used at compile time. |
| 59 | + ||| |
| 60 | + ||| @type The type-level value's type. |
| 61 | + ||| @pred The dependent type that requires an instance of `type`. |
| 62 | + public export |
| 63 | + data Subset : (type : Type) |
| 64 | + -> (pred : type -> Type) |
| 65 | + -> Type |
| 66 | + where |
| 67 | + Element : (value : type) |
| 68 | + -> (0 prf : pred value) |
| 69 | + -> Subset type pred |
| 70 | + |
| 71 | + ||| Return the type-level value (evidence) required by the dependent type. |
| 72 | + ||| |
| 73 | + ||| @type The type-level value's type. |
| 74 | + ||| @pred The dependent type that requires an instance of `type`. |
| 75 | + ||| @prf That there is a value that satisfies `prf`. |
| 76 | + public export |
| 77 | + fst : {0 type : Type} |
| 78 | + -> {0 pred : type -> Type} |
| 79 | + -> (1 prf : Subset type pred) |
| 80 | + -> type |
| 81 | + fst (Element value prf) = value |
| 82 | + |
| 83 | + ||| Return the dependently typed value. |
| 84 | + ||| |
| 85 | + ||| We need to be in the erased setting for this to work. |
| 86 | + ||| |
| 87 | + ||| @type The type-level value's type. |
| 88 | + ||| @pred The dependent type that requires an instance of `type`. |
| 89 | + ||| @prf That there is a value that satisfies `prf`. |
| 90 | + public export |
| 91 | + 0 |
| 92 | + snd : {0 type : Type} |
| 93 | + -> {0 pred : type -> Type} |
| 94 | + -> (1 value : Subset type pred) |
| 95 | + -> pred (Subset.fst value) |
| 96 | + snd (Element value prf) = prf |
0 commit comments