From 8db8f6f03971d338814c75cfff03cb6a3f72b3d2 Mon Sep 17 00:00:00 2001 From: John David Pressman Date: Fri, 7 Feb 2020 20:17:13 -0800 Subject: [PATCH] Add list reference page to docs and add unit tests for List.size --- gitlab-pages/docs/reference/list.md | 140 ++++++++++++++++++++++++++++ src/test/contracts/list.ligo | 3 +- src/test/contracts/list.mligo | 2 + src/test/contracts/list.religo | 2 + src/test/integration_tests.ml | 2 + src/test/md_file_tests.ml | 1 + 6 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 gitlab-pages/docs/reference/list.md diff --git a/gitlab-pages/docs/reference/list.md b/gitlab-pages/docs/reference/list.md new file mode 100644 index 000000000..569c7f013 --- /dev/null +++ b/gitlab-pages/docs/reference/list.md @@ -0,0 +1,140 @@ +--- +id: list-reference +title: List +--- + +## List.size(lst: a' list) : nat + +Get the number of elements in a list. + + + + +```pascaligo +function size_ (const m : list(int)) : nat is size(m) +``` + + +```cameligo +let size_ (s: int list) : nat = List.size s +``` + + +```reasonligo +let size_ = (s: list(int)): nat => List.size(s); +``` + + + +## List.length(lst: a' list) : nat + +Alias of `List.size`. + +## List.map(map_function: a' -> a', lst: a' list) : 'a list + +Apply an operation defined by `map_function` to each element of a list and return +a list of the modified elements. + + + +```pascaligo group=b +function increment(const i: int): int is block { skip } with i + 1; +// Creates a new list with elements incremented by 1 +const incremented_list: list(int) = list_map(increment, list 1; 2; 3; end ); +``` + + + +```cameligo group=b +let increment (i: int) : int = i + 1 +(* Creates a new list with elements incremented by 1 *) +let incremented_list: int list = List.map increment [1; 2; 3] +``` + + + + +```reasonligo group=b +let increment = (i: int): int => i + 1; +(* Creates a new list with elements incremented by 1 *) +let incremented_list: list(int) = List.map(increment, [1, 2, 3]); +``` + + + +## List.iter(iter_function: a' -> unit, lst: a' list) : unit + +Apply a side effecting function `iter_function` to each element of a list with no +return value. This is useful for asserting that each element of a list satisfies +a particular property. + + + + +```pascaligo +function iter_op (const s : list(int)) : int is + begin + var r : int := 0 ; + function aggregate (const i : int) : unit is + begin + r := r + i ; + end with unit ; + list_iter(aggregate, s) ; + end with r +``` + + +```cameligo +let iter_op (s : int list) : unit = + let do_nothing = fun (_: int) -> unit + in List.iter do_nothing s +``` + + +```reasonligo +let iter_op = (s: list(int)): unit => { + let do_nothing = (z: int) => unit; + List.iter(do_nothing, s); +}; +``` + + + +## List.fold(fold_function: (a' * a') -> a', lst: a' list, acc: a') : 'a + +Combine the elements of a list into one value using the operation defined by +`fold_function'. For example, you could define summation by folding a list of +integers. Starting with some initial accumulator value `acc`, the fold: + +1. Consumes an element of the list. +2. Passes the accumulator value to `fold_function` along with the element to produce +a new accumulated value. +3. The new accumulated value replaces the previous one. +4. IF there are still elements in the list go back to 1, ELSE return the accumulator + +Summation would be defined then by using a `fold_function` that takes two integers and +adds them together. Each step of the fold would consume an element from the list +and add it to the total until you've summed over the list. + + + +```pascaligo group=b +function sum(const result: int; const i: int): int is result + i; +const sum_of_a_list: int = list_fold(sum, list 1; 2; 3; end, 0); +``` + + + +```cameligo group=b +let sum (result, i: int * int) : int = result + i +let sum_of_a_list: int = List.fold sum [1; 2; 3] 0 +``` + + + +```reasonligo group=b +let sum = ((result, i): (int, int)): int => result + i; +let sum_of_a_list: int = List.fold(sum, [1, 2, 3], 0); +``` + + diff --git a/src/test/contracts/list.ligo b/src/test/contracts/list.ligo index 77f8beec3..2e02c2e85 100644 --- a/src/test/contracts/list.ligo +++ b/src/test/contracts/list.ligo @@ -11,8 +11,7 @@ const fb2 : foobar = 144 # fb const fb3 : foobar = cons(688 , fb2) -function size_ (const m : foobar) : nat is - block {skip} with (size(m)) +function size_ (const m : foobar) : nat is size(m) // function hdf (const m : foobar) : int is begin skip end with hd(m) diff --git a/src/test/contracts/list.mligo b/src/test/contracts/list.mligo index dfcad6a0b..06a914514 100644 --- a/src/test/contracts/list.mligo +++ b/src/test/contracts/list.mligo @@ -13,6 +13,8 @@ let main (p, s: param * storage) = | hd::tl -> s.0 + hd, tl in ([] : operation list), storage +let size_ (s: int list) : nat = List.size s + let fold_op (s: int list) : int = let aggregate = fun (t: int * int) -> t.0 + t.1 in List.fold aggregate s 10 diff --git a/src/test/contracts/list.religo b/src/test/contracts/list.religo index c54a445fc..9f9a2ec1c 100644 --- a/src/test/contracts/list.religo +++ b/src/test/contracts/list.religo @@ -17,6 +17,8 @@ let main2 = (p: param, storage) => { let main = (x: (param, storage)) => main2(x[0],x[1]); +let size_ = (s: list(int)): nat => List.size(s); + let fold_op = (s: list(int)): int => { let aggregate = (prec_cur: (int, int)) => prec_cur[0] + prec_cur[1]; List.fold(aggregate, s, 10); diff --git a/src/test/integration_tests.ml b/src/test/integration_tests.ml index 13d03872e..46777e09a 100644 --- a/src/test/integration_tests.ml +++ b/src/test/integration_tests.ml @@ -1564,6 +1564,7 @@ let match_matej_re () : unit result = let mligo_list () : unit result = let%bind program = mtype_file "./contracts/list.mligo" in + let%bind () = expect_eq program "size_" (e_list [e_int 0; e_int 1; e_int 2]) (e_nat 3) in let aux lst = e_list @@ List.map e_int lst in let%bind () = expect_eq program "fold_op" (aux [ 1 ; 2 ; 3 ]) (e_int 16) in let%bind () = @@ -1585,6 +1586,7 @@ let mligo_list () : unit result = let religo_list () : unit result = let%bind program = retype_file "./contracts/list.religo" in + let%bind () = expect_eq program "size_" (e_list [e_int 0; e_int 1; e_int 2]) (e_nat 3) in let aux lst = e_list @@ List.map e_int lst in let%bind () = expect_eq program "fold_op" (aux [ 1 ; 2 ; 3 ]) (e_int 16) in let%bind () = diff --git a/src/test/md_file_tests.ml b/src/test/md_file_tests.ml index 86aefeb89..91419879a 100644 --- a/src/test/md_file_tests.ml +++ b/src/test/md_file_tests.ml @@ -122,6 +122,7 @@ let md_files = [ "/gitlab-pages/docs/advanced/timestamps-addresses.md"; "/gitlab-pages/docs/api/cli-commands.md"; "/gitlab-pages/docs/api/cheat-sheet.md"; + "/gitlab-pages/docs/reference/list.md"; ] let md_root = "../../gitlab-pages/docs/language-basics/"