From 8fcc3c851ef5bf90391920233b6f8b468e399534 Mon Sep 17 00:00:00 2001 From: Sophie Kirschner Date: Mon, 20 Nov 2017 11:45:53 +0100 Subject: [PATCH] Reverse function now accepts unidrectional unknown-bounds inputs Previously it would always cause an arguments error Related to https://github.com/pineapplemachine/higher/issues/161 --- src/core/expecting.js | 17 +++++++++++++++++ src/functions/reverse.js | 20 +++++++++----------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/core/expecting.js b/src/core/expecting.js index 0102466..10c61b0 100644 --- a/src/core/expecting.js +++ b/src/core/expecting.js @@ -534,6 +534,23 @@ export const expecting = { return sequence; }, }), + notUnidirectionalUnboundedSequence: Expecting({ + type: "sequence", + article: "a", + singular: "bidirectional or not-known-unbounded sequence", + plural: "bidirectional or not-known-unbounded sequences", + adjective: "bidirectional or not-known-unbounded", + short: "sequence", + sequence: true, + transforms: true, + validate: value => { + const sequence = asSequence(value); + if(!sequence || (sequence.unbounded() && !sequence.back)){ + throw new Error(); + } + return sequence; + }, + }), exactly: option => Expecting({ article: "exactly", singular: String(option), diff --git a/src/functions/reverse.js b/src/functions/reverse.js index 8ef6eef..f40d977 100644 --- a/src/functions/reverse.js +++ b/src/functions/reverse.js @@ -120,8 +120,8 @@ export const ReverseSequence = defineSequence({ // Implementation for reversing a known-bounded unidirectional sequence. export const ReverseOnDemandSequence = function(source){ return new OnDemandSequence(ReverseSequence.appliedTo(ArraySequence), { - bounded: () => true, - unbounded: () => false, + bounded: () => source.bounded(), + unbounded: () => source.unbounded(), done: () => source.done(), back: () => source.front(), length: source.nativeLength ? () => source.nativeLength() : undefined, @@ -161,15 +161,12 @@ export const reverse = wrap({ ReverseSequence ], arguments: { - one: wrap.expecting.either( - wrap.expecting.bidirectionalSequence, - wrap.expecting.boundedSequence - ), + one: wrap.expecting.notUnidirectionalUnboundedSequence, }, implementation: function reverse(source){ if(source.back){ return new ReverseSequence(source); - }else{ // Argument validation implies source.bounded() + }else{ return ReverseOnDemandSequence(source); } }, @@ -197,14 +194,15 @@ export const reverse = wrap({ hi.assert(seq.startsWith("olleholleholleh")); hi.assert(seq.endsWith("olleholleholleh")); }, + "notKnownBoundedUnidirectionalInput": hi => { + const seq = () => hi.recur(i => i + 1).seed(1).until(i => i >= 8); + hi.assertEqual(seq(), [1, 2, 3, 4, 5, 6, 7]); + hi.assertEqual(seq().reverse(), [7, 6, 5, 4, 3, 2, 1]); + }, "unboundedUnidirectionalInput": hi => { const seq = hi.recur(i => i + "!").seed("hello"); hi.assertFail(() => seq.reverse()); }, - "notKnownBoundedUnidirectionalInput": hi => { - const seq = hi.recur(i => i + 1).seed(1).until(i => i >= 8); - hi.assertFail(() => seq.reverse()); - }, }, });