From 7ae6955066801a4248bf6bcc516d2398ec212179 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Mon, 25 Feb 2019 20:24:24 -0600 Subject: [PATCH] FEATURE: Add head and tail functions to our list library. --- docsite/site/content/stdlib/lists.md | 20 +++++++++++++++++++- std/lists.ucg | 18 ++++++++++++++++++ std/tests/lists_test.ucg | 10 ++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/docsite/site/content/stdlib/lists.md b/docsite/site/content/stdlib/lists.md index ed02de0..f4d0c41 100644 --- a/docsite/site/content/stdlib/lists.md +++ b/docsite/site/content/stdlib/lists.md @@ -36,7 +36,7 @@ l.str_join{ ## len -The len module returns the length of a list. It has a single required parameter. +The len function returns the length of a list. It has a single required parameter. * `list` The list to reverse. @@ -45,6 +45,24 @@ let l = import "std/lists.ucg"; l.len{list=[0, 1, 2, 3]} == 4; ``` +## head and tail + +The `tail` function returns the tail of a list minus it's head. + +``` +let l = import "std/lists.ucg"; +let tail = l.tail([0,1,2,3]); +tail == [1,2,3]; +``` + +The `head` function returns the head of the list as a list of one item. + +``` +let l = import "std/lists.ucg"; +let hd = l.head([0,1,2,3]); +tail == [0]; +``` + ## enumerate The enumerate module enumerates the elements of a list. It has three parameters. diff --git a/std/lists.ucg b/std/lists.ucg index 41342fe..a58cd7c 100644 --- a/std/lists.ucg +++ b/std/lists.ucg @@ -29,6 +29,24 @@ let len = func(list) => reduce(func(acc, item) => acc + 1, 0, list); // Reverses the provided list. let reverse = func(list) => reduce(func (acc, item) => [item] + acc, [], list); +// head returns the first item in a list as a list of one item. +// This function is safe for empty list inputs but is not safe +// for NULL inputs. +let head = func(list) => select len(list) > 0, [], { + true = [list.0], +}; + +// tail returns the tail of a list without the head. +// This function is safe for empty lists but is not safe +// for NULL inputs. +let tail = func(list) => reduce( + func (acc, item) => select acc.count > 0, acc{count=1, tail=[]}, { + true = acc{count = acc.count + 1, tail = acc.tail + [item]}, + }, + {count=0}, + list, +).tail; + // Enumerates the provided list with optional start and step parameters for the // enumeration. Prodices a list of pairs with the numeration and the list item. // diff --git a/std/tests/lists_test.ucg b/std/tests/lists_test.ucg index ad6431c..2339524 100644 --- a/std/tests/lists_test.ucg +++ b/std/tests/lists_test.ucg @@ -42,4 +42,14 @@ assert asserts.equal{ assert asserts.equal{ left=list.zip{list1=[0, 1], list2=[3, 4]}, right=[[0, 3], [1, 4]], +}; + +assert asserts.equal{ + left=list.tail([0,1,2,3,4]), + right=[1,2,3,4], +}; + +assert asserts.equal{ + left=list.head([0,1,2,3,4]), + right=[0], }; \ No newline at end of file