aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/abstract/equivalence.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/lux/abstract/equivalence.lux')
-rw-r--r--stdlib/source/lux/abstract/equivalence.lux42
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))))))