(.require [library [lux (.except left right) [abstract [equivalence (.only Equivalence)] [hash (.only Hash)]]]]) (with_template [ ] [(def .public ( value) (All (_ left right) (-> (Or left right))) {0 value})] [#0 left] [#1 right]) (def .public (either on_left on_right) (All (_ a b c) (-> (-> a c) (-> b c) (-> (Or a b) c))) (function (_ input) (case input {0 #0 l} (on_left l) {0 #1 r} (on_right r)))) (def .public (then on_left on_right) (All (_ l l' r r') (-> (-> l l') (-> r r') (-> (Or l r) (Or l' r')))) (function (_ input) (case input {0 #0 l} {0 #0 (on_left l)} {0 #1 r} {0 #1 (on_right r)}))) (with_template [ ] [(def .public ( items) (All (_ a b) (-> (List (Or a b)) (List ))) (case items {.#End} {.#End} {.#Item {0 x} items'} {.#Item [x ( items')]} {.#Item _ items'} ( items')))] [lefts a #0] [rights b #1] ) (def .public (partition xs) (All (_ a b) (-> (List (Or a b)) [(List a) (List b)])) (case xs {.#End} [{.#End} {.#End}] {.#Item x xs'} (let [[lefts rights] (partition xs')] (case x {0 #0 x'} [{.#Item x' lefts} rights] {0 #1 x'} [lefts {.#Item x' rights}])))) (def .public (equivalence left right) (All (_ l r) (-> (Equivalence l) (Equivalence r) (Equivalence (Or l r)))) (implementation (def (= reference sample) (case [reference sample] [{.#Left reference} {.#Left sample}] (at left = reference sample) [{.#Right reference} {.#Right sample}] (at right = reference sample) _ false)))) (def .public (hash left right) (All (_ l r) (-> (Hash l) (Hash r) (Hash (Or l r)))) (implementation (def equivalence (..equivalence (at left equivalence) (at right equivalence))) (def (hash value) (.nat (case value {.#Left value} ("lux i64 *" +2 (.int (at left hash value))) {.#Right value} ("lux i64 *" +3 (.int (at right hash value))))))))