(.require [library [lux (.except) [abstract [monad (.only do)]] [control ["[0]" try (.only Try)] ["[0]" exception]] [math [number ["i" int]]] ["[0]" meta (.only) ["[0]" code (.only) ["<[1]>" \\parser]] [macro [syntax (.only syntax)]] [type ["[0]" nominal (.except def)]]]]]) (exception.def .public zero_cannot_be_a_modulus) (nominal.def .public (Modulus %) Int (def .public (modulus value) (Ex (_ %) (-> Int (Try (Modulus %)))) (if (i.= +0 value) (exception.except ..zero_cannot_be_a_modulus []) {try.#Success (abstraction value)})) (def .public divisor (All (_ %) (-> (Modulus %) Int)) (|>> representation)) (def .public (= reference subject) (All (_ %r %s) (-> (Modulus %r) (Modulus %s) Bit)) (i.= (representation reference) (representation subject))) (def .public (congruent? modulus reference subject) (All (_ %) (-> (Modulus %) Int Int Bit)) (|> subject (i.- reference) (i.% (representation modulus)) (i.= +0))) ) (def .public literal (syntax (_ [divisor .int]) (meta.of_try (do try.monad [_ (..modulus divisor)] (in (list (` (try.trusted (..modulus (, (code.int divisor)))))))))))