From 8ccd0ef839c4c0b166482a7b2080664824341a81 Mon Sep 17 00:00:00 2001 From: Taeer Bar-Yam Date: Thu, 13 Jul 2023 10:31:10 -0400 Subject: [PATCH 1/5] add std.contract.Sequence --- core/stdlib/std.ncl | 21 +++++++++++++++++++ .../integration/fail/contracts/sequence.ncl | 6 ++++++ .../integration/pass/contracts/contracts.ncl | 6 ++++++ 3 files changed, 33 insertions(+) create mode 100644 core/tests/integration/fail/contracts/sequence.ncl diff --git a/core/stdlib/std.ncl b/core/stdlib/std.ncl index e4c4e4ec02..e9e42505ec 100644 --- a/core/stdlib/std.ncl +++ b/core/stdlib/std.ncl @@ -934,6 +934,27 @@ "% = fun pred label value => if pred value then value else %blame% label, + Sequence + | doc m%" + Apply multiple contracts from left to right. + + Type: `Array Contract -> Contract` + (for technical reasons, this function isn't actually statically typed) + + # Examples + + ```nickel + x | std.contract.Sequence [ Foo Bar ] + ``` + + is equivalent to + + ```nickel + (x | Foo) | Bar + ``` + "% + = fun contracts label value => + std.array.fold_right (fun contract acc => std.contract.apply contract label acc) value contracts, label | doc m%" The label submodule provides functions that manipulate the label diff --git a/core/tests/integration/fail/contracts/sequence.ncl b/core/tests/integration/fail/contracts/sequence.ncl new file mode 100644 index 0000000000..6628c5ba6b --- /dev/null +++ b/core/tests/integration/fail/contracts/sequence.ncl @@ -0,0 +1,6 @@ +# test.type = 'error' +# +# [test.metadata] +# error = 'EvalError::BlameError' + +3 | std.contract.Sequence [ Number, std.contract.from_predicate (fun x => x < 5), std.contract.from_predicate (fun x => x > 5) ] diff --git a/core/tests/integration/pass/contracts/contracts.ncl b/core/tests/integration/pass/contracts/contracts.ncl index c5fa20e4c5..04f92b97f7 100644 --- a/core/tests/integration/pass/contracts/contracts.ncl +++ b/core/tests/integration/pass/contracts/contracts.ncl @@ -166,5 +166,11 @@ let {check, Assert, ..} = import "../lib/assert.ncl" in = fun r => %record_insert% "g" r g in let res = f { z = 3 } in true, + + # std.contract.Sequence + let three = 3 | std.contract.Sequence [ Number, std.contract.from_predicate (fun x => x < 5) ] in + # preserves order + let tag = "some_tag" | std.contract.Sequence [ std.enum.TagOrString, [| 'some_tag |] ] + in true ] |> check From 3efb523360f1f955235f3d24b818d93d3ccc3fb0 Mon Sep 17 00:00:00 2001 From: Taeer Bar-Yam Date: Wed, 19 Jul 2023 03:21:15 -0400 Subject: [PATCH 2/5] nickel lists have `,` Co-authored-by: Viktor Kleen --- core/stdlib/std.ncl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/stdlib/std.ncl b/core/stdlib/std.ncl index e9e42505ec..d8ec5bf090 100644 --- a/core/stdlib/std.ncl +++ b/core/stdlib/std.ncl @@ -944,7 +944,7 @@ # Examples ```nickel - x | std.contract.Sequence [ Foo Bar ] + x | std.contract.Sequence [ Foo, Bar ] ``` is equivalent to From 719c17d6c299dc1c51843cefdddfc4857832e043 Mon Sep 17 00:00:00 2001 From: Taeer Bar-Yam Date: Wed, 19 Jul 2023 03:23:37 -0400 Subject: [PATCH 3/5] eta reduction Co-authored-by: Yann Hamdaoui --- core/stdlib/std.ncl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/stdlib/std.ncl b/core/stdlib/std.ncl index d8ec5bf090..e4e6749802 100644 --- a/core/stdlib/std.ncl +++ b/core/stdlib/std.ncl @@ -954,7 +954,7 @@ ``` "% = fun contracts label value => - std.array.fold_right (fun contract acc => std.contract.apply contract label acc) value contracts, + std.array.fold_right (fun contract => std.contract.apply contract label) value contracts, label | doc m%" The label submodule provides functions that manipulate the label From 0f3dc24dcc4fe22da3edfd18ac7336c09919deac Mon Sep 17 00:00:00 2001 From: Taeer Bar-Yam Date: Wed, 19 Jul 2023 03:28:13 -0400 Subject: [PATCH 4/5] example where it's actually useful --- core/stdlib/std.ncl | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/core/stdlib/std.ncl b/core/stdlib/std.ncl index e4e6749802..f01c423c55 100644 --- a/core/stdlib/std.ncl +++ b/core/stdlib/std.ncl @@ -952,6 +952,20 @@ ```nickel (x | Foo) | Bar ``` + + This is useful in positions where one cannot apply multiple contracts, + such as an argument to another contract: + + ```nickel + x | Array (std.contract.sequence [ Foo, Bar ]) + ``` + + Or stored in a variable: + + ```nickel + let C = std.contract.sequence [ Foo, Bar ] in + x | C + ``` "% = fun contracts label value => std.array.fold_right (fun contract => std.contract.apply contract label) value contracts, From 35c2405e2e5edcf4db10e972d14539c471c3c7c8 Mon Sep 17 00:00:00 2001 From: Taeer Bar-Yam Date: Wed, 19 Jul 2023 03:29:27 -0400 Subject: [PATCH 5/5] capitalisation --- core/stdlib/std.ncl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/stdlib/std.ncl b/core/stdlib/std.ncl index f01c423c55..2010f902d1 100644 --- a/core/stdlib/std.ncl +++ b/core/stdlib/std.ncl @@ -957,13 +957,13 @@ such as an argument to another contract: ```nickel - x | Array (std.contract.sequence [ Foo, Bar ]) + x | Array (std.contract.Sequence [ Foo, Bar ]) ``` Or stored in a variable: ```nickel - let C = std.contract.sequence [ Foo, Bar ] in + let C = std.contract.Sequence [ Foo, Bar ] in x | C ``` "%