diff options
Diffstat (limited to 'stdlib/source/lux/abstract/equivalence.lux')
-rw-r--r-- | stdlib/source/lux/abstract/equivalence.lux | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/stdlib/source/lux/abstract/equivalence.lux b/stdlib/source/lux/abstract/equivalence.lux new file mode 100644 index 000000000..b773505de --- /dev/null +++ b/stdlib/source/lux/abstract/equivalence.lux @@ -0,0 +1,42 @@ +(.module: + [lux #*] + [// + [functor (#+ Contravariant)]]) + +(signature: #export (Equivalence a) + {#.doc "Equivalence for a type's instances."} + (: (-> a a Bit) + =)) + +(def: #export (product left right) + (All [l r] (-> (Equivalence l) (Equivalence r) (Equivalence [l r]))) + (structure + (def: (= [a b] [x y]) + (and (:: left = a x) + (:: right = b y))))) + +(def: #export (sum left right) + (All [l r] (-> (Equivalence l) (Equivalence r) (Equivalence (| l r)))) + (structure + (def: (= a|b x|y) + (case [a|b x|y] + [(0 a) (0 x)] + (:: left = a x) + + [(1 b) (1 y)] + (:: right = b y) + + _ + #0)))) + +(def: #export (rec sub) + (All [a] (-> (-> (Equivalence a) (Equivalence a)) (Equivalence a))) + (structure + (def: (= left right) + (sub (rec sub) left right)))) + +(structure: #export contravariant (Contravariant Equivalence) + (def: (map-1 f equivalence) + (structure + (def: (= reference sample) + (:: equivalence = (f reference) (f sample)))))) |