... Inspired by; ... "The Different Aspects of Monads and Mixins" by Bruno C. d. S. Oliveira (.using [library [lux (.except open) ["[0]" type] [abstract [hash (.only Hash)] [monad (.only do)]] [control ["[0]" state (.only State)]] [data ["[0]" product] [collection ["[0]" dictionary (.only Dictionary)]]]]] ["[0]" // ["[1]" mixin (.only Mixin Recursive)]]) (def: .public memoization (All (_ i o) (Mixin i (State (Dictionary i o) o))) (function (_ delegate recur) (function (_ input) (do [! state.monad] [memory state.get] (case (dictionary.value input memory) {.#Some output} (in output) {.#None} (do ! [output (delegate input) _ (state.update (dictionary.has input output))] (in output))))))) (type: .public (Memo i o) (Recursive i (State (Dictionary i o) o))) (def: .public (open memo) (All (_ i o) (type.let [Memory (Dictionary i o)] (-> (Memo i o) (-> [Memory i] [Memory o])))) (let [memo (//.fixed (//.mixed ..memoization (//.of_recursive memo)))] (function (_ [memory input]) (|> input memo (state.result memory))))) (def: .public (closed hash memo) (All (_ i o) (-> (Hash i) (Memo i o) (-> i o))) (let [memo (//.fixed (//.mixed ..memoization (//.of_recursive memo))) empty (dictionary.empty hash)] (|>> memo (state.result empty) product.right))) (def: .public (none hash memo) (All (_ i o) (-> (Hash i) (Memo i o) (-> i o))) (let [memo (//.fixed (//.of_recursive memo)) empty (dictionary.empty hash)] (|>> memo (state.result empty) product.right)))