diff options
author | Eduardo Julian | 2019-09-15 22:02:27 -0400 |
---|---|---|
committer | Eduardo Julian | 2019-09-15 22:02:27 -0400 |
commit | ea20cbf9d1e9226da7a8d060c7e30e8ab815436d (patch) | |
tree | 9caef11a8e7c44c7c0ff05d9cc177daccdb87b60 | |
parent | 9ad08a087e22502e337fbde1b0adecb3f7d3e7eb (diff) |
Implemented mixin-style function composition.
-rw-r--r-- | stdlib/source/lux/control/function/mixin.lux | 63 | ||||
-rw-r--r-- | stdlib/source/test/lux.lux | 10 |
2 files changed, 69 insertions, 4 deletions
diff --git a/stdlib/source/lux/control/function/mixin.lux b/stdlib/source/lux/control/function/mixin.lux new file mode 100644 index 000000000..4a79bb99a --- /dev/null +++ b/stdlib/source/lux/control/function/mixin.lux @@ -0,0 +1,63 @@ +## Inspired by; +## "The Different Aspects of Monads and Mixins" by Bruno C. d. S. Oliveira + +(.module: + [lux #* + [abstract + [monoid (#+ Monoid)] + [predicate (#+ Predicate)] + [monad (#+ Monad do)]]]) + +(type: #export (Mixin m) + (-> m m m)) + +(def: #export (mixin f) + (All [i o] (-> (Mixin (-> i o)) (-> i o))) + (function (mix input) + ((f mix mix) input))) + +(def: #export nothing + Mixin + (function (_ super self) + super)) + +(def: #export (inherit parent child) + (All [m] (-> (Mixin m) (Mixin m) (Mixin m))) + (function (_ super self) + (parent (child super self) self))) + +(structure: #export monoid + (All [m] (Monoid (Mixin m))) + + (def: identity ..nothing) + (def: compose ..inherit)) + +(type: #export (Recursive i o) + (-> (-> i o) (-> i o))) + +(def: #export (from-recursive recursive) + (All [i o] (-> (Recursive i o) (Mixin (-> i o)))) + (function (_ delegate recur) + (recursive recur))) + +(def: #export (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: #export (before monad action) + (All [! i o] (-> (Monad !) (-> i (! Any)) (Mixin (-> i (! o))))) + (function (_ delegate recur input) + (do monad + [_ (action input)] + (delegate input)))) + +(def: #export (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)] + (wrap output)))) diff --git a/stdlib/source/test/lux.lux b/stdlib/source/test/lux.lux index db3a84ce7..22208adcc 100644 --- a/stdlib/source/test/lux.lux +++ b/stdlib/source/test/lux.lux @@ -3,9 +3,10 @@ [structure (#+)] [function (#+)] [reference (#+)] - [case (#+)] - [loop (#+)] - [extension (#+)])] + ## [case (#+)] + ## [loop (#+)] + ## [extension (#+)] + )] (.module: ["/" lux #* [abstract @@ -13,7 +14,8 @@ [predicate (#+ Predicate)]] [control ["." io (#+ io)] - ["." function] + ["." function + [mixin (#+)]] [parser [cli (#+ program:)]]] [data |