ucg 0.5.7

A configuration generation grammar.
Documentation
// 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.
//
// * or - runs a user provided function of no arguments if the value is NULL.
//         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,
} => ({do=do, is_null=is_null, or=or, 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 or = func (op) => select (mod.val == NULL), maybe{val=mod.val}, {
        true = maybe{val=op()},
    };

    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;