From 49087b7a5bd622e283153258b8fb155a3fbcf916 Mon Sep 17 00:00:00 2001 From: Dierk Koenig Date: Fri, 8 Sep 2023 17:53:44 +0200 Subject: [PATCH] refactor: move createMonadicSequence into the sequencePrototype module to resolve some cyclic/bidirectional dependency issues. This way we also make sure that whoever creates a sequence has all the functions on the prototype. --- .../primeNumberSequence.js | 2 +- .../squareNumberSequence.js | 2 +- docs/src/kolibri/json/jsonMonad.js | 2 +- .../sequence/constructors/range/rangeTest.js | 2 +- .../kolibri/sequence/constructors/seq/seq.js | 2 +- .../stackSequence/stackSequence.js | 2 +- .../tupleSequence/tupleSequence.js | 4 +- .../sequence/constructors/unfold/unfold.js | 2 +- .../sequence/operators/catMaybes/catMaybes.js | 2 +- .../kolibri/sequence/operators/cycle/cycle.js | 2 +- .../kolibri/sequence/operators/drop/drop.js | 2 +- .../sequence/operators/dropWhile/dropWhile.js | 2 +- .../src/kolibri/sequence/operators/map/map.js | 2 +- .../sequence/operators/mconcat/mconcat.js | 2 +- .../sequence/operators/reverse/reverse.js | 2 +- .../kolibri/sequence/operators/take/take.js | 2 +- .../sequence/operators/takeWhere/takeWhere.js | 2 +- .../sequence/operators/takeWhile/takeWhile.js | 2 +- .../sequence/operators/zipWith/zipWith.js | 2 +- docs/src/kolibri/sequence/sequenceBuilder.js | 2 +- .../terminalOperations/uncons/uncons.js | 2 +- .../sequenceUtil/createMonadicSequence.js | 25 ------- .../util/sequenceUtil/sequencePrototype.js | 72 +++++++++++-------- 23 files changed, 65 insertions(+), 76 deletions(-) delete mode 100644 docs/src/kolibri/sequence/util/sequenceUtil/createMonadicSequence.js diff --git a/docs/src/examples/sequence/generators/primeNumberSequence/primeNumberSequence.js b/docs/src/examples/sequence/generators/primeNumberSequence/primeNumberSequence.js index 5da45bcc..a70fb1e5 100644 --- a/docs/src/examples/sequence/generators/primeNumberSequence/primeNumberSequence.js +++ b/docs/src/examples/sequence/generators/primeNumberSequence/primeNumberSequence.js @@ -1,5 +1,5 @@ import { Just, Nothing } from "../../../../kolibri/stdlib.js"; -import { createMonadicSequence } from "../../../../kolibri/sequence/util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../../../../kolibri/sequence/util/sequenceUtil/sequencePrototype.js"; import { choiceMaybe } from "../../../../kolibri/stdlib/stdlib.js"; import { uncurry } from "../../../../kolibri/lambda/church.js"; import { iteratorOf } from "../../../../kolibri/sequence/util/sequenceUtil/iteratorOf.js"; diff --git a/docs/src/examples/sequence/generators/squareNumberSequence/squareNumberSequence.js b/docs/src/examples/sequence/generators/squareNumberSequence/squareNumberSequence.js index bd90ee94..0d80362d 100644 --- a/docs/src/examples/sequence/generators/squareNumberSequence/squareNumberSequence.js +++ b/docs/src/examples/sequence/generators/squareNumberSequence/squareNumberSequence.js @@ -1,6 +1,6 @@ import { Sequence } from "../../../../kolibri/sequence/sequence.js" import { iteratorOf } from "../../../../kolibri/sequence/util/sequenceUtil/iteratorOf.js"; -import { createMonadicSequence } from "../../../../kolibri/sequence/util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../../../../kolibri/sequence/util/sequenceUtil/sequencePrototype.js"; export { SquareNumberSequence } diff --git a/docs/src/kolibri/json/jsonMonad.js b/docs/src/kolibri/json/jsonMonad.js index 50b0f4e4..04d22871 100644 --- a/docs/src/kolibri/json/jsonMonad.js +++ b/docs/src/kolibri/json/jsonMonad.js @@ -1,6 +1,6 @@ import { Just, Nothing } from "../stdlib/maybe.js"; import { iteratorOf } from "../sequence/util/sequenceUtil/iteratorOf.js"; -import { createMonadicSequence } from "../sequence/util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../sequence/util/sequenceUtil/sequencePrototype.js"; import { PureSequence, nil, diff --git a/docs/src/kolibri/sequence/constructors/range/rangeTest.js b/docs/src/kolibri/sequence/constructors/range/rangeTest.js index 76a3f870..a6bf10b7 100644 --- a/docs/src/kolibri/sequence/constructors/range/rangeTest.js +++ b/docs/src/kolibri/sequence/constructors/range/rangeTest.js @@ -1,7 +1,7 @@ import { Range, Walk} from "./range.js"; import { TestSuite } from "../../../util/test.js"; import { iteratorOf } from "../../util/sequenceUtil/iteratorOf.js"; -import { createMonadicSequence } from "../../util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../../util/sequenceUtil/sequencePrototype.js"; import { addToTestingTable, TESTS } from "../../util/testingTable.js"; import { createTestConfig } from "../../util/testUtil.js"; diff --git a/docs/src/kolibri/sequence/constructors/seq/seq.js b/docs/src/kolibri/sequence/constructors/seq/seq.js index 2acb538c..64b5041f 100644 --- a/docs/src/kolibri/sequence/constructors/seq/seq.js +++ b/docs/src/kolibri/sequence/constructors/seq/seq.js @@ -1,4 +1,4 @@ -import { createMonadicSequence } from "../../util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../../util/sequenceUtil/sequencePrototype.js"; export { Seq } diff --git a/docs/src/kolibri/sequence/constructors/stackSequence/stackSequence.js b/docs/src/kolibri/sequence/constructors/stackSequence/stackSequence.js index 752762bd..510dfa28 100644 --- a/docs/src/kolibri/sequence/constructors/stackSequence/stackSequence.js +++ b/docs/src/kolibri/sequence/constructors/stackSequence/stackSequence.js @@ -1,6 +1,6 @@ import { pop, emptyStack, stackEquals } from "../../../../../../contrib/p6_brodwolf_andermatt/src/stack/stack.js"; import { fst, snd } from "../../../stdlib.js"; -import { createMonadicSequence } from "../../util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../../util/sequenceUtil/sequencePrototype.js"; import { toJsBool } from "../../../lambda/church.js"; export { StackSequence } diff --git a/docs/src/kolibri/sequence/constructors/tupleSequence/tupleSequence.js b/docs/src/kolibri/sequence/constructors/tupleSequence/tupleSequence.js index 580e55dd..5703bb6f 100644 --- a/docs/src/kolibri/sequence/constructors/tupleSequence/tupleSequence.js +++ b/docs/src/kolibri/sequence/constructors/tupleSequence/tupleSequence.js @@ -1,7 +1,7 @@ import { map } from "../../operators/map/map.js"; import { Sequence } from "../sequence/Sequence.js"; import { iteratorOf } from "../../util/sequenceUtil/iteratorOf.js"; -import { createMonadicSequence } from "../../util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../../util/sequenceUtil/sequencePrototype.js"; export { TupleSequence } @@ -34,4 +34,4 @@ const TupleSequence = tuple => { }; return createMonadicSequence(tupleIterator); -}; \ No newline at end of file +}; diff --git a/docs/src/kolibri/sequence/constructors/unfold/unfold.js b/docs/src/kolibri/sequence/constructors/unfold/unfold.js index d9a67b9c..27ff5295 100644 --- a/docs/src/kolibri/sequence/constructors/unfold/unfold.js +++ b/docs/src/kolibri/sequence/constructors/unfold/unfold.js @@ -2,7 +2,7 @@ * @module kolibri.sequence.constructors.unfold * The idea was thankfully provided by Daniel Kröni. */ -import {createMonadicSequence} from "../../util/sequenceUtil/createMonadicSequence.js"; +import {createMonadicSequence} from "../../util/sequenceUtil/sequencePrototype.js"; export { unfold } /** diff --git a/docs/src/kolibri/sequence/operators/catMaybes/catMaybes.js b/docs/src/kolibri/sequence/operators/catMaybes/catMaybes.js index 0e11a2f9..dc5cd700 100644 --- a/docs/src/kolibri/sequence/operators/catMaybes/catMaybes.js +++ b/docs/src/kolibri/sequence/operators/catMaybes/catMaybes.js @@ -1,5 +1,5 @@ import { iteratorOf } from "../../util/sequenceUtil/iteratorOf.js"; -import { createMonadicSequence} from "../../util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence} from "../../util/sequenceUtil/sequencePrototype.js"; import { catMaybes as arrCatMaybes } from "../../../stdlib/stdlib.js"; export { catMaybes } diff --git a/docs/src/kolibri/sequence/operators/cycle/cycle.js b/docs/src/kolibri/sequence/operators/cycle/cycle.js index 2ff29678..d9b3fd55 100644 --- a/docs/src/kolibri/sequence/operators/cycle/cycle.js +++ b/docs/src/kolibri/sequence/operators/cycle/cycle.js @@ -1,5 +1,5 @@ import { iteratorOf } from "../../util/sequenceUtil/iteratorOf.js"; -import { createMonadicSequence } from "../../util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../../util/sequenceUtil/sequencePrototype.js"; /** * {@link cycle} ties a finite {@link Iterable} into a circular one, or equivalently, diff --git a/docs/src/kolibri/sequence/operators/drop/drop.js b/docs/src/kolibri/sequence/operators/drop/drop.js index a59caabf..ee06bab7 100644 --- a/docs/src/kolibri/sequence/operators/drop/drop.js +++ b/docs/src/kolibri/sequence/operators/drop/drop.js @@ -1,6 +1,6 @@ import { dropWhile } from "../dropWhile/dropWhile.js"; import { iteratorOf } from "../../util/sequenceUtil/iteratorOf.js"; -import { createMonadicSequence } from "../../util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../../util/sequenceUtil/sequencePrototype.js"; export { drop } diff --git a/docs/src/kolibri/sequence/operators/dropWhile/dropWhile.js b/docs/src/kolibri/sequence/operators/dropWhile/dropWhile.js index c2166011..da6ad8b4 100644 --- a/docs/src/kolibri/sequence/operators/dropWhile/dropWhile.js +++ b/docs/src/kolibri/sequence/operators/dropWhile/dropWhile.js @@ -1,5 +1,5 @@ import { iteratorOf } from "../../util/sequenceUtil/iteratorOf.js"; -import { createMonadicSequence } from "../../util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../../util/sequenceUtil/sequencePrototype.js"; export { dropWhile } diff --git a/docs/src/kolibri/sequence/operators/map/map.js b/docs/src/kolibri/sequence/operators/map/map.js index e9f47e29..554b7fc6 100644 --- a/docs/src/kolibri/sequence/operators/map/map.js +++ b/docs/src/kolibri/sequence/operators/map/map.js @@ -1,5 +1,5 @@ import { iteratorOf } from "../../util/sequenceUtil/iteratorOf.js"; -import { createMonadicSequence } from "../../util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../../util/sequenceUtil/sequencePrototype.js"; export { map } diff --git a/docs/src/kolibri/sequence/operators/mconcat/mconcat.js b/docs/src/kolibri/sequence/operators/mconcat/mconcat.js index 054362c1..a5b64e87 100644 --- a/docs/src/kolibri/sequence/operators/mconcat/mconcat.js +++ b/docs/src/kolibri/sequence/operators/mconcat/mconcat.js @@ -1,5 +1,5 @@ import { iteratorOf } from "../../util/sequenceUtil/iteratorOf.js"; -import { createMonadicSequence } from "../../util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../../util/sequenceUtil/sequencePrototype.js"; export { mconcat } diff --git a/docs/src/kolibri/sequence/operators/reverse/reverse.js b/docs/src/kolibri/sequence/operators/reverse/reverse.js index 73723d28..e51e9041 100644 --- a/docs/src/kolibri/sequence/operators/reverse/reverse.js +++ b/docs/src/kolibri/sequence/operators/reverse/reverse.js @@ -1,5 +1,5 @@ import { iteratorOf } from "../../util/sequenceUtil/iteratorOf.js"; -import { createMonadicSequence } from "../../util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../../util/sequenceUtil/sequencePrototype.js"; export { reverse$ } diff --git a/docs/src/kolibri/sequence/operators/take/take.js b/docs/src/kolibri/sequence/operators/take/take.js index aaa8c742..e1833827 100644 --- a/docs/src/kolibri/sequence/operators/take/take.js +++ b/docs/src/kolibri/sequence/operators/take/take.js @@ -1,5 +1,5 @@ import { iteratorOf } from "../../util/sequenceUtil/iteratorOf.js"; -import { createMonadicSequence } from "../../util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../../util/sequenceUtil/sequencePrototype.js"; export { take } diff --git a/docs/src/kolibri/sequence/operators/takeWhere/takeWhere.js b/docs/src/kolibri/sequence/operators/takeWhere/takeWhere.js index 709898ad..11fb009f 100644 --- a/docs/src/kolibri/sequence/operators/takeWhere/takeWhere.js +++ b/docs/src/kolibri/sequence/operators/takeWhere/takeWhere.js @@ -1,5 +1,5 @@ import { iteratorOf } from "../../util/sequenceUtil/iteratorOf.js"; -import { createMonadicSequence } from "../../util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../../util/sequenceUtil/sequencePrototype.js"; export { takeWhere } diff --git a/docs/src/kolibri/sequence/operators/takeWhile/takeWhile.js b/docs/src/kolibri/sequence/operators/takeWhile/takeWhile.js index c5fce2f4..8e33341a 100644 --- a/docs/src/kolibri/sequence/operators/takeWhile/takeWhile.js +++ b/docs/src/kolibri/sequence/operators/takeWhile/takeWhile.js @@ -1,5 +1,5 @@ import { iteratorOf } from "../../util/sequenceUtil/iteratorOf.js"; -import { createMonadicSequence } from "../../util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../../util/sequenceUtil/sequencePrototype.js"; export { takeWhile } diff --git a/docs/src/kolibri/sequence/operators/zipWith/zipWith.js b/docs/src/kolibri/sequence/operators/zipWith/zipWith.js index d1cb22c1..12a3a9d0 100644 --- a/docs/src/kolibri/sequence/operators/zipWith/zipWith.js +++ b/docs/src/kolibri/sequence/operators/zipWith/zipWith.js @@ -1,5 +1,5 @@ import { iteratorOf } from "../../util/sequenceUtil/iteratorOf.js"; -import { createMonadicSequence } from "../../util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../../util/sequenceUtil/sequencePrototype.js"; export { zipWith } diff --git a/docs/src/kolibri/sequence/sequenceBuilder.js b/docs/src/kolibri/sequence/sequenceBuilder.js index 2dd3bc97..eda0036a 100644 --- a/docs/src/kolibri/sequence/sequenceBuilder.js +++ b/docs/src/kolibri/sequence/sequenceBuilder.js @@ -1,5 +1,5 @@ import { nil } from "./constructors/nil/nil.js"; -import { createMonadicSequence } from "./util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "./util/sequenceUtil/sequencePrototype.js"; import { isIterable } from "./util/sequenceUtil/isIterable.js"; import { iteratorOf } from "./util/sequenceUtil/iteratorOf.js"; diff --git a/docs/src/kolibri/sequence/terminalOperations/uncons/uncons.js b/docs/src/kolibri/sequence/terminalOperations/uncons/uncons.js index 6ad461c5..d5970643 100644 --- a/docs/src/kolibri/sequence/terminalOperations/uncons/uncons.js +++ b/docs/src/kolibri/sequence/terminalOperations/uncons/uncons.js @@ -1,7 +1,7 @@ // noinspection GrazieInspection import { iteratorOf } from "../../util/sequenceUtil/iteratorOf.js"; -import { createMonadicSequence } from "../../util/sequenceUtil/createMonadicSequence.js"; +import { createMonadicSequence } from "../../util/sequenceUtil/sequencePrototype.js"; import { Pair } from "../../../stdlib/pair.js"; export { uncons } diff --git a/docs/src/kolibri/sequence/util/sequenceUtil/createMonadicSequence.js b/docs/src/kolibri/sequence/util/sequenceUtil/createMonadicSequence.js deleted file mode 100644 index f1aa9f89..00000000 --- a/docs/src/kolibri/sequence/util/sequenceUtil/createMonadicSequence.js +++ /dev/null @@ -1,25 +0,0 @@ -import { SequencePrototype } from "./sequencePrototype.js"; - -export { createMonadicSequence, setPrototype }; - -/** - * - * @template _T_ - * @param { Iterable<_T_> } iterable - * @returns { SequenceType<_T_> } - */ -const setPrototype = iterable => { - Object.setPrototypeOf(iterable, SequencePrototype); - return /**@type SequenceType*/ iterable; -}; - -/** - * Builds an {@link SequenceType} from a given {@link Iterator}. - * @template _T_ - * @param { () => Iterator<_T_> } iterator - * @returns { SequenceType<_T_> } - */ -const createMonadicSequence = iterator => { - const result = {[Symbol.iterator]: iterator}; - return setPrototype(result); -}; diff --git a/docs/src/kolibri/sequence/util/sequenceUtil/sequencePrototype.js b/docs/src/kolibri/sequence/util/sequenceUtil/sequencePrototype.js index df9dea19..22e91971 100644 --- a/docs/src/kolibri/sequence/util/sequenceUtil/sequencePrototype.js +++ b/docs/src/kolibri/sequence/util/sequenceUtil/sequencePrototype.js @@ -3,6 +3,7 @@ import { PureSequence } from "../../constructors/pureSequence/pureSequence.js"; import { isIterable } from "./isIterable.js"; import { LoggerFactory } from "../../../logger/loggerFactory.js"; +import { nil } from "../../constructors/nil/nil.js"; import { append, bind, @@ -23,21 +24,45 @@ import { takeWhile, zip, zipWith -} from "../../operators/operators.js"; +} from "../../operators/operators.js"; import { eq$, show -} from "../../terminalOperations/terminalOperations.js"; +} from "../../terminalOperations/terminalOperations.js"; const log = LoggerFactory("kolibri.sequence"); -export { SequencePrototype } +export { SequencePrototype, createMonadicSequence } + +/** + * This function object serves as prototype for the {@link SequenceType}. + * Singleton object. + */ +function SequencePrototype () { } // does nothing on purpose + /** - * This function serves as prototype for the {@link SequenceType}. * + * @template _T_ + * @param { Iterable<_T_> } iterable + * @returns { SequenceType<_T_> } */ -const SequencePrototype = () => null; +function setPrototype (iterable) { + Object.setPrototypeOf(iterable, SequencePrototype); + return /**@type SequenceType*/ iterable; +} +/** + * Builds an {@link SequenceType} by decorating a given {@link Iterator}. + * @template _T_ + * @param { () => Iterator<_T_> } iteratorConstructor - a function that returns an {@link Iterator} + * @returns { SequenceType<_T_> } + */ +function createMonadicSequence (iteratorConstructor) { + const iterable = { [Symbol.iterator]: iteratorConstructor }; // make a new iterable object + return setPrototype(iterable); +} + +// monadic sequence operations ---------------------------------- SequencePrototype.and = function (bindFn) { return bind(bindFn)(this); @@ -49,21 +74,9 @@ SequencePrototype.fmap = function (mapper) { SequencePrototype.pure = val => PureSequence(val); -SequencePrototype.empty = () => { - const emptySequence = () => { - const iterator = () => { - const next = () => ({ done: true, value: undefined }); - return { next }; - }; - - return {[Symbol.iterator]: iterator}; - }; +SequencePrototype.empty = () => nil; - const nil = emptySequence(); - Object.setPrototypeOf(nil, SequencePrototype); - - return /** @type SequenceType */ nil; -}; +// terminal sequence operations ---------------------------------- SequencePrototype.show = function (maxValues = 50) { return show(this, maxValues); @@ -75,9 +88,6 @@ SequencePrototype.toString = function (maxValues = 50) { } return show(this, maxValues); }; -SequencePrototype.pipe = function(...transformers) { - return pipe(...transformers)(this); -}; SequencePrototype.eq$ = function(that) { if (!isIterable(that)) return false; @@ -86,7 +96,7 @@ SequencePrototype.eq$ = function(that) { SequencePrototype["=="] = SequencePrototype.eq$; -// all the SequenceOperations are added to the prototype +// "semigroup-like" sequence operations ------------------------------------- SequencePrototype.append = function (sequence) { return append(this)(sequence); @@ -121,6 +131,16 @@ SequencePrototype.forEach = function (callback) { return forEach(callback)(this); }; +SequencePrototype.map = SequencePrototype.fmap; + +SequencePrototype.mconcat = function () { + return mconcat(this); +}; + +SequencePrototype.pipe = function(...transformers) { + return pipe(...transformers)(this); +}; + SequencePrototype.reverse$ = function () { return reverse$(this); }; @@ -141,12 +161,6 @@ SequencePrototype.takeWhile = function (predicate) { return takeWhile(predicate)(this); }; -SequencePrototype.map = SequencePrototype.fmap; - -SequencePrototype.mconcat = function () { - return mconcat(this); -}; - SequencePrototype.zip = function (iterable) { return zip(this)(iterable); };