(.module: [lux #* [control ["." state] ["ex" exception (#+ Exception exception:)] [monad (#+ do)]] [data ["." product] ["." error (#+ Error)] ["." text format]] [macro ["s" syntax (#+ syntax:)]]]) (type: #export (Operation s o) (state.State' Error s o)) (def: #export Monad (state.Monad error.Monad)) (type: #export (Phase s i o) (-> i (Operation s o))) (def: #export (run' state operation) (All [s o] (-> s (Operation s o) (Error [s o]))) (operation state)) (def: #export (run state operation) (All [s o] (-> s (Operation s o) (Error o))) (|> state operation (:: error.Monad map product.right))) (def: #export fail (-> Text Operation) (|>> error.fail (state.lift error.Monad))) (def: #export (throw exception parameters) (All [e] (-> (Exception e) e Operation)) (state.lift error.Monad (ex.throw exception parameters))) (syntax: #export (assert exception message test) (wrap (list (` (if (~ test) (:: ..Monad (~' wrap) []) (..throw (~ exception) (~ message))))))) (def: #export (with-stack exception message action) (All [e s o] (-> (Exception e) e (Operation s o) (Operation s o))) (<<| (ex.with-stack exception message) action)) (def: #export identity (All [s a] (Phase s a a)) (function (_ input state) (#error.Success [state input]))) (def: #export (compose pre post) (All [s0 s1 i t o] (-> (Phase s0 i t) (Phase s1 t o) (Phase [s0 s1] i o))) (function (_ input [pre/state post/state]) (do error.Monad [[pre/state' temp] (pre input pre/state) [post/state' output] (post temp post/state)] (wrap [[pre/state' post/state'] output])))) (type: #export Eval (-> Type Code (Error Any)))