mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-21 18:10:42 -04:00
FEATURE: Ops module wrapper idioms for stdlib.
This commit is contained in:
parent
0e2e396ac3
commit
4afac26497
@ -1,5 +1,5 @@
|
||||
// maybe is our monadic optional. It wraps a value that may or may not be the empty
|
||||
// type NULL. It exports three operations.
|
||||
// type NULL. It exports the following operations.
|
||||
//
|
||||
// * do - runs a user provided function of one argument on the value.
|
||||
// Returns a maybe wrapped result.
|
||||
|
@ -138,4 +138,45 @@ let zip = module{
|
||||
|
||||
// The resulting zipped list.
|
||||
let result = reduce(reducer, acc, rng).result;
|
||||
};
|
||||
|
||||
// Wraps a list and provides a number of helpful operations.
|
||||
//
|
||||
// * len - property the length of the wrapped list.
|
||||
//
|
||||
// * str_join - function joins list into string with provided separator `sep`.
|
||||
//
|
||||
// * slice - function returns a slice of the list from `start` to `end`.
|
||||
//
|
||||
// * enumerate - function returns a list of pairs of [index, value] from the list.
|
||||
// The returned list is wrapped in the ops module.
|
||||
//
|
||||
// * head - function returns the head of the list as list of one item.
|
||||
//
|
||||
// * tail - function returns the tail of the list.
|
||||
// The returned list is wrapped in the ops module.
|
||||
//
|
||||
// * reverse - function returns the list reversed.
|
||||
// The returned list is wrapped in the ops module.
|
||||
let ops = module{
|
||||
list=NULL,
|
||||
} => ({len=len,
|
||||
str_join=str_join,
|
||||
slice=slice,
|
||||
enumerate=enumerate,
|
||||
tail=tail,
|
||||
head=head,
|
||||
reverse=reverse,
|
||||
list=list,
|
||||
}) {
|
||||
let super = import "std/lists.ucg";
|
||||
let list = mod.list;
|
||||
let len = super.len(mod.list);
|
||||
let str_join = func(sep) => super.str_join{list=mod.list, sep=sep};
|
||||
|
||||
let slice = func(start, end) => super.slice{start=start, end=end, list=mod.list};
|
||||
let enumerate = func() => super.ops{list=super.enumerate{start=0, step=1, list=mod.list}};
|
||||
let tail = func() => super.ops{list=super.tail(mod.list)};
|
||||
let head = func() => super.head(mod.list);
|
||||
let reverse = func() => super.ops{list=super.reverse(mod.list)};
|
||||
};
|
@ -1,7 +1,29 @@
|
||||
// Wraps a string and provides operations for that string.
|
||||
//
|
||||
// * len - property representing the length of the string in characters.
|
||||
//
|
||||
// * str - property the wrapped string.
|
||||
//
|
||||
// * split_on - module that splits the string on a character.
|
||||
// - `on` field represents the character to split on.
|
||||
// - `str` field defaults to the wrapped string. you can override this
|
||||
// if desired.
|
||||
//
|
||||
// * split_at - function splits the wrapped string at an character index.
|
||||
//
|
||||
// * substr - module that returns a substr of the wrapped string.
|
||||
// - `start` field is the index at which the substr starts (defaults to 0)
|
||||
// - `end` field is the index at which the substr ends (defaults to end of string)
|
||||
let ops = module {
|
||||
str="",
|
||||
} => {
|
||||
} => ({len=len,
|
||||
str=str,
|
||||
split_on=split_on,
|
||||
split_at=split_at,
|
||||
substr=substr,
|
||||
}) {
|
||||
let len = import "std/lists.ucg".len(mod.str);
|
||||
let str = mod.str;
|
||||
|
||||
let split_on = module{
|
||||
on=" ",
|
||||
@ -20,7 +42,7 @@ let ops = module {
|
||||
|
||||
let result = accumulated.out + [accumulated.buf];
|
||||
};
|
||||
|
||||
|
||||
let split_at = func(idx) => filter(
|
||||
func(name, val) => name != "counter",
|
||||
reduce(
|
||||
@ -43,13 +65,14 @@ let ops = module {
|
||||
start = 0,
|
||||
end = len,
|
||||
} => (result) {
|
||||
let filepkg = import "std/strings.ucg";
|
||||
let reducer = func(acc, char) => acc{
|
||||
counter = acc.counter + 1,
|
||||
str = select ((acc.counter >= mod.start) && (acc.counter <= mod.end)), acc.str, {
|
||||
true = acc.str + char,
|
||||
},
|
||||
};
|
||||
let result = reduce(
|
||||
reducer, {counter = 0, str = ""}, mod.str).str;
|
||||
let result = filepkg.ops{str=reduce(
|
||||
reducer, {counter = 0, str = ""}, mod.str).str};
|
||||
};
|
||||
};
|
@ -7,7 +7,7 @@ let ok = module{
|
||||
// descriptive message to use in output.
|
||||
desc=todo_desc,
|
||||
} => ({ok=ok, desc=desc}) {
|
||||
assert mod.desc != NULL;
|
||||
(mod.desc != NULL) || fail "description can't be null";
|
||||
|
||||
let ok = mod.test;
|
||||
let desc = "@" % (mod.desc);
|
||||
@ -20,7 +20,7 @@ let not_ok = module{
|
||||
// descriptive message to use in output.
|
||||
desc=todo_desc,
|
||||
} => ({ok=ok, desc=desc}) {
|
||||
assert mod.desc != NULL;
|
||||
(mod.desc != NULL) || fail "description can't be null";
|
||||
|
||||
let ok = not mod.test;
|
||||
let desc = "@" % (mod.desc);
|
||||
@ -35,7 +35,7 @@ let equal = module{
|
||||
right=NULL,
|
||||
desc="",
|
||||
} => ({ok=ok, desc=desc}) {
|
||||
assert mod.desc != NULL;
|
||||
(mod.desc != NULL) || fail "description can't be null";
|
||||
|
||||
let ok = mod.left == mod.right;
|
||||
let desc = select (mod.desc == ""), "@ == @" % (mod.left, mod.right), {
|
||||
@ -51,7 +51,7 @@ let not_equal = module{
|
||||
right=NULL,
|
||||
desc="",
|
||||
} => ({ok=ok, desc=desc}) {
|
||||
assert mod.desc != NULL;
|
||||
(mod.desc != NULL) || fail "description can't be null";
|
||||
|
||||
let ok = mod.left != mod.right;
|
||||
let desc = select (mod.desc == ""), "@ != @" % (mod.left, mod.right), {
|
||||
|
@ -4,22 +4,22 @@ let asserts = import "std/testing.ucg";
|
||||
let list_to_join = [1, 2, 3];
|
||||
|
||||
assert asserts.equal{
|
||||
left=list.str_join{sep=",", list=list_to_join},
|
||||
left=list.ops{list=list_to_join}.str_join(","),
|
||||
right="1,2,3"
|
||||
};
|
||||
|
||||
assert asserts.equal{
|
||||
left=list.len([0, 1, 2, 3]),
|
||||
left=list.ops{list=[0, 1, 2, 3]}.len,
|
||||
right=4,
|
||||
};
|
||||
|
||||
assert asserts.equal{
|
||||
left = list.reverse([0, 1, 2, 3]),
|
||||
left = list.ops{list=[0, 1, 2, 3]}.reverse().list,
|
||||
right = [3, 2, 1, 0],
|
||||
};
|
||||
|
||||
assert asserts.equal{
|
||||
left=list.enumerate{list=["foo", "bar"]},
|
||||
left=list.ops{list=["foo", "bar"]}.enumerate().list,
|
||||
right=[[0, "foo"], [1, "bar"]],
|
||||
};
|
||||
|
||||
@ -48,10 +48,15 @@ assert asserts.equal{
|
||||
};
|
||||
|
||||
assert asserts.equal{
|
||||
left=list.head([0,1,2,3,4]),
|
||||
left=list.ops{list=[0,1,2,3,4]}.head(),
|
||||
right=[0],
|
||||
};
|
||||
|
||||
assert asserts.equal{
|
||||
left=list.ops{list=[0,1,2,3,4]}.tail().list,
|
||||
right=[1,2,3,4],
|
||||
};
|
||||
|
||||
assert asserts.equal{
|
||||
left=list.slice{end=2, list=[0,1,2,3]},
|
||||
right=[0,1,2],
|
||||
|
@ -29,16 +29,16 @@ assert asserts.equal{
|
||||
};
|
||||
|
||||
assert asserts.equal{
|
||||
left = str_class.substr{start=1},
|
||||
left = str_class.substr{start=1}.str,
|
||||
right = "oo bar",
|
||||
};
|
||||
|
||||
assert asserts.equal{
|
||||
left = str_class.substr{end=5},
|
||||
left = str_class.substr{end=5}.str,
|
||||
right = "foo ba",
|
||||
};
|
||||
|
||||
assert asserts.equal{
|
||||
left = str_class.substr{end=8},
|
||||
left = str_class.substr{end=8}.str,
|
||||
right = "foo bar",
|
||||
};
|
@ -6,16 +6,31 @@ assert t.equal{
|
||||
right = ["foo", "bar"],
|
||||
};
|
||||
|
||||
assert t.equal{
|
||||
left = tpl.ops{tpl={foo=1, bar=2}}.fields(),
|
||||
right = ["foo", "bar"],
|
||||
};
|
||||
|
||||
assert t.equal{
|
||||
left = tpl.values{tpl={foo=1, bar=2}},
|
||||
right = [1, 2],
|
||||
};
|
||||
|
||||
assert t.equal{
|
||||
left = tpl.ops{tpl={foo=1, bar=2}}.values(),
|
||||
right = [1, 2],
|
||||
};
|
||||
|
||||
assert t.equal{
|
||||
left = tpl.iter{tpl={foo=1, bar=2}},
|
||||
right = [["foo", 1], ["bar", 2]],
|
||||
};
|
||||
|
||||
assert t.equal{
|
||||
left = tpl.ops{tpl={foo=1, bar=2}}.iter(),
|
||||
right = [["foo", 1], ["bar", 2]],
|
||||
};
|
||||
|
||||
assert t.equal{
|
||||
left = tpl.strip_nulls{tpl={foo="bar", bar=NULL}},
|
||||
right = {foo="bar"},
|
||||
|
@ -36,6 +36,25 @@ let iter = module{
|
||||
let result = reduce(func (acc, field, value) => acc + [[field, value]], [], (mod.tpl));
|
||||
};
|
||||
|
||||
// Wraps a tuple and provides a number of operations on it.
|
||||
//
|
||||
// * fields - function returns all the fields in the wrapped tuple as a list.
|
||||
//
|
||||
// * values - function returns all the values in the wrapped tuple as a list.
|
||||
//
|
||||
// * iter - function returns a list of pairs of [field, value].
|
||||
let ops = module{
|
||||
tpl = NULL,
|
||||
} => ({fields=fields, values=values, iter=iter}) {
|
||||
(mod.tpl != NULL) || fail "tpl must not be null";
|
||||
|
||||
let super = import "std/tuples.ucg";
|
||||
|
||||
let fields = func() => super.fields{tpl=mod.tpl};
|
||||
let values = func() => super.values{tpl=mod.tpl};
|
||||
let iter = func() => super.iter{tpl=mod.tpl};
|
||||
};
|
||||
|
||||
// Strip all the null fields from a tuple.
|
||||
let strip_nulls = module{
|
||||
tpl = NULL,
|
||||
|
Loading…
x
Reference in New Issue
Block a user