diff --git a/std/functional.ucg b/std/functional.ucg index 32ef535..1f41622 100644 --- a/std/functional.ucg +++ b/std/functional.ucg @@ -1,17 +1,32 @@ +// maybe is our monadic optional. It wraps a value that may or may not be the empty +// type NULL. It exports three operations. +// +// * do - runs a user provided function of one argument on the value. +// Returns a maybe wrapped result. +// +// * is_null - a function with no arguments that returns true if the value is +// NULL and false if it is not. +// +// * unwrap - returns the wrapped value from the maybe. +// +// * expect - Throws a compile error if the value is NULL. let maybe = module{ val = NULL, -} => { - let do = func (op) => select (mod.val != NULL), NULL, { - true = op(mod.val), - }; -}; - -let if = module{ - test = false, -} => { - let do = func (op, arg) => select mod.test, arg, { - true = op(arg), +} => ({do=do, is_null=is_null, unwrap=unwrap, expect=expect}) { + let maybe = import "std/functional.ucg".maybe; + + let do = func (op) => select (mod.val != NULL), maybe{val=NULL}, { + true = maybe{val=op(mod.val)}, + }; + + let is_null = func() => mod.val == NULL; + + let unwrap = func() => mod.val; + + let expect = func(msg) => select mod.val != NULL, fail msg, { + true = mod.val, }; }; +// identity is the identity function. let identity = func (arg) => arg; \ No newline at end of file diff --git a/std/tests/functional_test.ucg b/std/tests/functional_test.ucg index e08da57..8aeaec4 100644 --- a/std/tests/functional_test.ucg +++ b/std/tests/functional_test.ucg @@ -1,28 +1,28 @@ -let t = (import "std/testing.ucg").asserts{}; -let f = (import "std/functional.ucg"); +let t = import "std/testing.ucg".asserts{}; +let f = import "std/functional.ucg"; let op = func (arg) => arg{foo="bar"}; assert t.equal{ - left = f.maybe{val=NULL}.do(op), + left = f.maybe{val=NULL}.do(op).unwrap(), right = NULL, }; -assert t.equal{ - left = f.maybe{val={}}.do(op), - right = {foo="bar"}, +assert t.ok{ + test = f.maybe{val=NULL}.is_null(), + desc = "maybe is null", +}; + +assert t.ok{ + test = f.maybe{val=NULL}.do(op).is_null(), + desc = "maybe is still null after an operation", }; assert t.equal{ - left = f.if{test=true}.do(op, {}), + left = f.maybe{val={}}.do(op).unwrap(), right = {foo="bar"}, }; -assert t.equal{ - left = f.if{test=false}.do(op, {}), - right = {}, -}; - assert t.equal{ left = f.identity("foo"), right = "foo",