... Inspired by; ... "The Different Aspects of Monads and Mixins" by Bruno C. d. S. Oliveira (.require [library [lux (.except) [abstract [monoid (.only Monoid)] [monad (.only Monad do)]] [control [function [predicate (.only Predicate)]]]]]) (type .public (Mixin i o) (-> (-> i o) (-> i o) (-> i o))) (def .public (fixed f) (All (_ i o) (-> (Mixin i o) (-> i o))) (function (mix input) ((f mix mix) input))) (def .public nothing Mixin (function (_ delegate recur) delegate)) (def .public (mixed parent child) (All (_ i o) (-> (Mixin i o) (Mixin i o) (Mixin i o))) (function (_ delegate recur) (parent (child delegate recur) recur))) (def .public monoid (All (_ i o) (Monoid (Mixin i o))) (implementation (def identity ..nothing) (def composite ..mixed))) (def .public (advice when then) (All (_ i o) (-> (Predicate i) (Mixin i o) (Mixin i o))) (function (_ delegate recur input) (if (when input) ((then delegate recur) input) (delegate input)))) (def .public (before monad action) (All (_ ! i o) (-> (Monad !) (-> i (! Any)) (Mixin i (! o)))) (function (_ delegate recur input) (do monad [_ (action input)] (delegate input)))) (def .public (after monad action) (All (_ ! i o) (-> (Monad !) (-> i o (! Any)) (Mixin i (! o)))) (function (_ delegate recur input) (do monad [output (delegate input) _ (action input output)] (in output)))) (type .public (Recursive i o) (-> (-> i o) (-> i o))) (def .public (of_recursive recursive) (All (_ i o) (-> (Recursive i o) (Mixin i o))) (function (_ delegate recur) (recursive recur)))