diff options
Diffstat (limited to '')
19 files changed, 251 insertions, 226 deletions
diff --git a/stdlib/source/lux/data/collection/sequence.lux b/stdlib/source/lux/data/collection/sequence.lux index 5755e8214..2b046fee8 100644 --- a/stdlib/source/lux/data/collection/sequence.lux +++ b/stdlib/source/lux/data/collection/sequence.lux @@ -4,79 +4,72 @@ [functor (#+ Functor)] [comonad (#+ CoMonad)]] [control - ["." continuation (#+ Cont pending)] - ["p" parser - ["s" code (#+ Parser)]]] + ["//" continuation (#+ Cont)] + ["<>" parser + ["<.>" code (#+ Parser)]]] [meta (#+ with-gensyms)] [macro - ["." code] - [syntax (#+ syntax:)]] + [syntax (#+ syntax:)] + ["." code]] [data ["." bit] [number ["n" nat]] [collection - ["." list ("#;." monad)]]]]) + ["." list ("#@." monad)]]]]) (type: #export (Sequence a) {#.doc "An infinite sequence of values."} (Cont [a (Sequence a)])) -(def: (cycle' x xs init full) - (All [a] - (-> a (List a) a (List a) (Sequence a))) - (case xs - #.Nil - (pending [x (cycle' init full init full)]) - - (#.Cons x' xs') - (pending [x (cycle' x' xs' init full)]))) - (def: #export (iterate f x) {#.doc "Create a sequence by applying a function to a value, and to its result, on and on..."} (All [a] (-> (-> a a) a (Sequence a))) - (pending [x (iterate f (f x))])) + (//.pending [x (iterate f (f x))])) (def: #export (repeat x) {#.doc "Repeat a value forever."} (All [a] (-> a (Sequence a))) - (pending [x (repeat x)])) + (//.pending [x (repeat x)])) -(def: #export (cycle xs) +(def: #export (cycle [start next]) {#.doc (doc "Go over the elements of a list forever." "The list should not be empty.")} (All [a] - (-> (List a) (Maybe (Sequence a)))) - (case xs - #.Nil - #.None - - (#.Cons x xs') - (#.Some (cycle' x xs' x xs')))) - -(template [<name> <return> <part>] - [(def: #export (<name> s) + (-> [a (List a)] (Sequence a))) + (loop [head start + tail next] + (//.pending [head (case tail + #.Nil + (recur start next) + + (#.Cons head' tail') + (recur head' tail'))]))) + +(template [<name> <return>] + [(def: #export (<name> sequence) (All [a] (-> (Sequence a) <return>)) - (let [[h t] (continuation.run s)] - <part>))] + (let [[head tail] (//.run sequence)] + <name>))] - [head a h] - [tail (Sequence a) t]) + [head a] + [tail (Sequence a)] + ) -(def: #export (nth idx s) +(def: #export (nth idx sequence) (All [a] (-> Nat (Sequence a) a)) - (let [[h t] (continuation.run s)] - (if (n.> 0 idx) - (nth (dec idx) t) - h))) + (let [[head tail] (//.run sequence)] + (case idx + 0 head + _ (nth (dec idx) tail)))) (template [<taker> <dropper> <splitter> <pred-type> <pred-test> <pred-step>] [(def: #export (<taker> pred xs) (All [a] (-> <pred-type> (Sequence a) (List a))) - (let [[x xs'] (continuation.run xs)] + (let [[x xs'] (//.run xs)] (if <pred-test> (list& x (<taker> <pred-step> xs')) (list)))) @@ -84,7 +77,7 @@ (def: #export (<dropper> pred xs) (All [a] (-> <pred-type> (Sequence a) (Sequence a))) - (let [[x xs'] (continuation.run xs)] + (let [[x xs'] (//.run xs)] (if <pred-test> (<dropper> <pred-step> xs') xs))) @@ -92,13 +85,13 @@ (def: #export (<splitter> pred xs) (All [a] (-> <pred-type> (Sequence a) [(List a) (Sequence a)])) - (let [[x xs'] (continuation.run xs)] + (let [[x xs'] (//.run xs)] (if <pred-test> (let [[tail next] (<splitter> <pred-step> xs')] [(#.Cons [x tail]) next]) [(list) xs])))] - [take-while drop-while split-while (-> a Bit) (pred x) pred] + [take-while drop-while split-while (-> a Bit) (pred x) pred] [take drop split Nat (n.> 0 pred) (dec pred)] ) @@ -107,14 +100,14 @@ (All [a b] (-> (-> a [a b]) a (Sequence b))) (let [[next x] (step init)] - (pending [x (unfold step next)]))) + (//.pending [x (unfold step next)]))) -(def: #export (filter p xs) +(def: #export (filter predicate sequence) (All [a] (-> (-> a Bit) (Sequence a) (Sequence a))) - (let [[x xs'] (continuation.run xs)] - (if (p x) - (pending [x (filter p xs')]) - (filter p xs')))) + (let [[head tail] (//.run sequence)] + (if (predicate head) + (//.pending [head (filter predicate tail)]) + (filter predicate tail)))) (def: #export (partition left? xs) {#.doc (doc "Split a sequence in two based on a predicate." @@ -123,29 +116,35 @@ (All [a] (-> (-> a Bit) (Sequence a) [(Sequence a) (Sequence a)])) [(filter left? xs) (filter (bit.complement left?) xs)]) -(structure: #export functor (Functor Sequence) +(structure: #export functor + (Functor Sequence) + (def: (map f fa) - (let [[h t] (continuation.run fa)] - (pending [(f h) (map f t)])))) + (let [[head tail] (//.run fa)] + (//.pending [(f head) (map f tail)])))) -(structure: #export comonad (CoMonad Sequence) +(structure: #export comonad + (CoMonad Sequence) + (def: &functor ..functor) + (def: unwrap head) + (def: (split wa) - (let [[head tail] (continuation.run wa)] - (pending [wa (split tail)])))) + (let [[head tail] (//.run wa)] + (//.pending [wa (split tail)])))) -(syntax: #export (^sequence& {patterns (s.form (p.many s.any))} +(syntax: #export (^sequence& {patterns (<code>.form (<>.many <code>.any))} body - {branches (p.some s.any)}) + {branches (<>.some <code>.any)}) {#.doc (doc "Allows destructuring of sequences in pattern-matching expressions." "Caveat emptor: Only use it for destructuring, and not for testing values within the sequences." (let [(^sequence& x y z _tail) (some-sequence-func +1 +2 +3)] (func x y z)))} (with-gensyms [g!sequence] - (let [body+ (` (let [(~+ (list;join (list;map (function (_ pattern) + (let [body+ (` (let [(~+ (list@join (list@map (function (_ pattern) (list (` [(~ pattern) (~ g!sequence)]) - (` ((~! continuation.run) (~ g!sequence))))) + (` ((~! //.run) (~ g!sequence))))) patterns)))] (~ body)))] (wrap (list& g!sequence body+ branches))))) diff --git a/stdlib/source/lux/data/collection/set.lux b/stdlib/source/lux/data/collection/set.lux index dfefcb1df..9321723c3 100644 --- a/stdlib/source/lux/data/collection/set.lux +++ b/stdlib/source/lux/data/collection/set.lux @@ -73,8 +73,7 @@ (All [a] (-> (Hash a) (Monoid (Set a)))) (def: identity (..new hash)) - (def: compose ..union) - ) + (def: compose ..union)) (def: #export empty? (All [a] (-> (Set a) Bit)) @@ -90,7 +89,7 @@ (def: #export (super? sub super) (All [a] (-> (Set a) (Set a) Bit)) - (sub? super sub)) + (..sub? super sub)) (def: #export predicate (All [a] (-> (Set a) (Predicate a))) diff --git a/stdlib/source/lux/data/format/json.lux b/stdlib/source/lux/data/format/json.lux index 643d12969..2dbe32d91 100644 --- a/stdlib/source/lux/data/format/json.lux +++ b/stdlib/source/lux/data/format/json.lux @@ -47,8 +47,8 @@ (template [<name> <type>] [(type: #export <name> <type>)] - [Array (Row JSON)] - [Object (Dictionary String JSON)] + [Array (Row JSON)] + [Object (Dictionary String JSON)] ) (def: #export object diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/jvm/debug.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/jvm/debug.lux index 142c46224..657566813 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/jvm/debug.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/jvm/debug.lux @@ -22,7 +22,7 @@ (do io.monad [outcome (do (try.with @) [file (: (IO (Try (File IO))) - (file.get-file io.monad file.system file-path))] + (file.get-file io.monad file.default file-path))] (!.use (:: file over-write) bytecode))] (wrap (case outcome (#try.Success definition) diff --git a/stdlib/source/lux/world/console.lux b/stdlib/source/lux/world/console.lux index a66743b65..c1ad4e7e5 100644 --- a/stdlib/source/lux/world/console.lux +++ b/stdlib/source/lux/world/console.lux @@ -71,7 +71,7 @@ (#static in java/io/InputStream) (#static out java/io/PrintStream)) - (def: #export system + (def: #export default (IO (Try (Console IO))) (do io.monad [?jvm-console (java/lang/System::console)] diff --git a/stdlib/source/lux/world/file.lux b/stdlib/source/lux/world/file.lux index 5f1bbc6a8..277a3018d 100644 --- a/stdlib/source/lux/world/file.lux +++ b/stdlib/source/lux/world/file.lux @@ -390,7 +390,7 @@ (function (discard _) (!delete path cannot-discard-directory)))))) - (`` (structure: #export system + (`` (structure: #export default (System IO) (~~ (template [<name> <method> <capability> <exception>] @@ -597,7 +597,7 @@ (function (discard _) (Fs::rmdirSync [path] (..node-fs []))))))) - (`` (structure: #export system + (`` (structure: #export default (System IO) (~~ (template [<name> <method> <capability> <exception>] @@ -1126,3 +1126,22 @@ (#try.Failure error) (wrap (#try.Failure error)))))))) ))) + +(def: #export (make-directories monad system path) + (All [!] (-> (Monad !) (System !) Path (! (Try Path)))) + (case (text.split-all-with (:: system separator) path) + #.Nil + (:: monad wrap (exception.throw ..cannot-create-directory [path])) + + (#.Cons head tail) + (loop [current head + next tail] + (do (try.with monad) + [_ (..get-directory monad system current)] + (case next + #.Nil + (wrap current) + + (#.Cons head tail) + (recur (format current (:: system separator) head) + tail)))))) diff --git a/stdlib/source/program/aedifex.lux b/stdlib/source/program/aedifex.lux index 76db24a47..485277d88 100644 --- a/stdlib/source/program/aedifex.lux +++ b/stdlib/source/program/aedifex.lux @@ -50,7 +50,7 @@ (def: (install! profile) (-> /.Profile (Promise Any)) (do promise.monad - [outcome (/local.install (file.async file.system) profile)] + [outcome (/local.install (file.async file.default) profile)] (wrap (case outcome (#try.Success _) (log! "Successfully installed locally!") @@ -63,14 +63,14 @@ (-> /.Profile (Promise Any)) (do promise.monad [outcome (do (try.with promise.monad) - [cache (/local.all-cached (file.async file.system) + [cache (/local.all-cached (file.async file.default) (set.to-list (get@ #/.dependencies profile)) /dependency.empty) resolution (promise.future (/dependency.resolve-all (set.to-list (get@ #/.repositories profile)) (set.to-list (get@ #/.dependencies profile)) cache))] - (/local.cache-all (file.async file.system) + (/local.cache-all (file.async file.default) resolution))] (wrap (case outcome (#try.Success _) @@ -82,12 +82,12 @@ (program: [{[profile operation] /cli.command}] (do {@ io.monad} - [?profile (/input.read io.monad file.system profile)] + [?profile (/input.read io.monad file.default profile)] (case ?profile (#try.Success profile) (case operation #/cli.POM - (exec (/command/pom.do! (file.async file.system) profile) + (exec (/command/pom.do! (file.async file.default) profile) (wrap [])) #/cli.Dependencies diff --git a/stdlib/source/program/aedifex/command/build.lux b/stdlib/source/program/aedifex/command/build.lux index 6a1ab93d4..2d8ffb763 100644 --- a/stdlib/source/program/aedifex/command/build.lux +++ b/stdlib/source/program/aedifex/command/build.lux @@ -89,7 +89,7 @@ (-> Resolution (List Path)) (|>> dictionary.keys (list.filter (|>> (get@ #///dependency.type) (text@= ///artifact/type.lux-library))) - (list@map (|>> (get@ #///dependency.artifact) (///local.path file.system))))) + (list@map (|>> (get@ #///dependency.artifact) (///local.path file.default))))) (import: java/lang/String) @@ -124,24 +124,24 @@ [(#.Some program) (#.Some target)] (do ///action.monad - [cache (///local.all-cached (file.async file.system) + [cache (///local.all-cached (file.async file.default) (set.to-list (get@ #///.dependencies profile)) ///dependency/resolution.empty) resolution (promise.future (///dependency/resolution.resolve-all (set.to-list (get@ #///.repositories profile)) (set.to-list (get@ #///.dependencies profile)) cache)) - _ (///local.cache-all (file.async file.system) + _ (///local.cache-all (file.async file.default) resolution) [resolution compiler] (promise@wrap (..compiler resolution)) working-directory (promise.future ..working-directory) #let [libraries (..libraries resolution) [prefix output] (case compiler - (#JVM artifact) [(format "java -jar " (///local.path file.system artifact)) + (#JVM artifact) [(format "java -jar " (///local.path file.default artifact)) "program.jar"] - (#JS artifact) [(format "node --stack_size=8192 " (///local.path file.system artifact)) + (#JS artifact) [(format "node --stack_size=8192 " (///local.path file.default artifact)) "program.js"]) - cache-directory (format working-directory (:: file.system separator) target) + cache-directory (format working-directory (:: file.default separator) target) command (format prefix " build" " " (..plural-parameter "--library" libraries) " " (..plural-parameter "--source" (set.to-list (get@ #///.sources profile))) @@ -151,5 +151,5 @@ outcome (///shell.execute command working-directory) #let [_ (log! "[BUILD ENDED]")]] (wrap [compiler - (format cache-directory (:: file.system separator) output)])) + (format cache-directory (:: file.default separator) output)])) )) diff --git a/stdlib/source/program/aedifex/command/deploy.lux b/stdlib/source/program/aedifex/command/deploy.lux index d7c7802b7..b8ac5c97c 100644 --- a/stdlib/source/program/aedifex/command/deploy.lux +++ b/stdlib/source/program/aedifex/command/deploy.lux @@ -65,7 +65,7 @@ content))))] (do {@ ///action.monad} [library (:: @ map (binary.run tar.writer) - (export.library (file.async file.system) + (export.library (file.async file.default) (set.to-list (get@ #/.sources profile)))) pom (promise@wrap (///pom.write profile)) _ (deploy! ///artifact/type.pom (|> pom (:: xml.codec encode) encoding.to-utf8)) diff --git a/stdlib/source/program/aedifex/local.lux b/stdlib/source/program/aedifex/local.lux index c7c72c827..674d99f04 100644 --- a/stdlib/source/program/aedifex/local.lux +++ b/stdlib/source/program/aedifex/local.lux @@ -26,7 +26,9 @@ ["." tar] ["." xml]]] [world - ["." file (#+ Path File Directory)]]] + ["." file (#+ Path File Directory)] + [net + ["." uri]]]] [program [compositor ["." export]]] @@ -40,31 +42,17 @@ ["#." dependency (#+ Dependency) ["#/." resolution (#+ Package Resolution)]]]) -(def: (local system) - (All [a] (-> (file.System a) Path)) - (format "~" (:: system separator) ".m2")) - (def: (repository system) (All [a] (-> (file.System a) Path)) - (format (..local system) (:: system separator) "repository")) + (let [/ (:: system separator)] + (format "~" / ".m2" / "repository"))) -(def: (guarantee-repository! system artifact) - (-> (file.System Promise) Artifact (Promise (Try Path))) - (do {@ (try.with promise.monad)} - [_ (: (Promise (Try (Directory Promise))) - (file.get-directory promise.monad system (..local system))) - #let [root (..repository system)] - _ (: (Promise (Try (Directory Promise))) - (file.get-directory promise.monad system root))] - (monad.fold @ - (function (_ child parent) - (do @ - [#let [path (format parent (:: system separator) child)] - _ (: (Promise (Try (Directory Promise))) - (file.get-directory promise.monad system path))] - (wrap path))) - root - (//artifact.local artifact)))) +(def: #export (path system artifact) + (All [a] (-> (file.System a) Artifact Path)) + (format (..repository system) + (:: system separator) + (text.replace-all uri.separator (:: system separator) + (//artifact.path artifact)))) (def: (save! system content file) (-> (file.System Promise) Binary Path (Promise (Try Any))) @@ -78,7 +66,8 @@ (case (get@ #/.identity profile) (#.Some identity) (do (try.with promise.monad) - [repository (..guarantee-repository! system identity) + [repository (: (Promise (Try Path)) + (file.make-directories promise.monad system (..path system identity))) #let [artifact-name (format repository (:: system separator) (//artifact.identity identity))] package (export.library system (set.to-list (get@ #/.sources profile))) _ (..save! system (binary.run tar.writer package) @@ -93,7 +82,8 @@ (def: #export (cache system [artifact type] package) (-> (file.System Promise) Dependency Package (Promise (Try Any))) (do (try.with promise.monad) - [directory (..guarantee-repository! system artifact) + [directory (: (Promise (Try Path)) + (file.make-directories promise.monad system (..path system artifact))) #let [prefix (format directory (:: system separator) (//artifact.identity artifact))] directory (: (Promise (Try (Directory Promise))) (file.get-directory promise.monad system directory)) @@ -129,7 +119,8 @@ (def: #export (cached system [artifact type]) (-> (file.System Promise) Dependency (Promise (Try Package))) (do (try.with promise.monad) - [directory (..guarantee-repository! system artifact) + [directory (: (Promise (Try Path)) + (file.make-directories promise.monad system (..path system artifact))) #let [prefix (format directory (:: system separator) (//artifact.identity artifact))] pom (..read! system (format prefix //artifact/extension.pom)) [pom dependencies] (:: promise.monad wrap @@ -175,9 +166,3 @@ (#try.Failure error) <next>))))) - -(def: #export (path system artifact) - (All [a] (-> (file.System a) Artifact Path)) - (format (..repository system) - (:: system separator) - (//artifact.identity artifact))) diff --git a/stdlib/source/program/compositor.lux b/stdlib/source/program/compositor.lux index 1b17a4de8..3bc870f9b 100644 --- a/stdlib/source/program/compositor.lux +++ b/stdlib/source/program/compositor.lux @@ -142,7 +142,7 @@ (:assume (platform.compile import static expander platform compilation [archive state]))}) _ (ioW.freeze (get@ #platform.&file-system platform) static archive) program-context (promise@wrap ($/program.context archive)) - _ (promise.future (..package! io.monad file.system packager,package static archive program-context))] + _ (promise.future (..package! io.monad file.default packager,package static archive program-context))] (wrap (log! "Compilation complete!")))) (#/cli.Export export) @@ -157,7 +157,7 @@ (undefined) ## (<| (or-crash! "Interpretation failed:") ## (do {@ promise.monad} - ## [console (|> console.system + ## [console (|> console.default ## promise.future ## (:: @ map (|>> try.assume console.async)))] ## (interpreter.run (try.with promise.monad) console platform interpretation generation-bundle))) diff --git a/stdlib/source/program/licentia.lux b/stdlib/source/program/licentia.lux index 7eab5b444..244e28223 100644 --- a/stdlib/source/program/licentia.lux +++ b/stdlib/source/program/licentia.lux @@ -57,7 +57,7 @@ (do io.monad [?done (: (IO (Try Any)) (do (try.with io.monad) - [file (!.use (:: file.system file) input) + [file (!.use (:: file.default file) input) blob (!.use (:: file content) []) document (io;wrap (do try.monad [raw-json (encoding.from-utf8 blob) @@ -69,7 +69,7 @@ license (json.run json /input.license)] (wrap (/output.license license)))) output-file (: (IO (Try (File IO))) - (file.get-file io.monad file.system output))] + (file.get-file io.monad file.default output))] (!.use (:: output-file over-write) (encoding.to-utf8 document))))] (case ?done (#try.Success _) diff --git a/stdlib/source/program/scriptum.lux b/stdlib/source/program/scriptum.lux index bf12da1cd..1cb0ee21a 100644 --- a/stdlib/source/program/scriptum.lux +++ b/stdlib/source/program/scriptum.lux @@ -489,7 +489,7 @@ (do io.monad [outcome (do (try.with io.monad) [target (: (IO (Try (File IO))) - (file.get-file io.monad file.system path))] + (file.get-file io.monad file.default path))] (!.use (:: target over-write) (encoding.to-utf8 (md.markdown documentation))))] (case outcome (#try.Failure error) diff --git a/stdlib/source/spec/lux/abstract/comonad.lux b/stdlib/source/spec/lux/abstract/comonad.lux index 3dfda0bbf..e434f6ab1 100644 --- a/stdlib/source/spec/lux/abstract/comonad.lux +++ b/stdlib/source/spec/lux/abstract/comonad.lux @@ -51,11 +51,11 @@ (== (|> start _@split (_@map (|>> _@split (_@map increase) decrease))) (|> start _@split (_@map increase) _@split (_@map decrease)))))) -(def: #export (spec injection comparison monad) +(def: #export (spec injection comparison subject) (All [f] (-> (Injection f) (Comparison f) (CoMonad f) Test)) (<| (_.with-cover [/.CoMonad]) ($_ _.and - (..left-identity injection monad) - (..right-identity injection comparison monad) - (..associativity injection comparison monad) + (..left-identity injection subject) + (..right-identity injection comparison subject) + (..associativity injection comparison subject) ))) diff --git a/stdlib/source/test/aedifex/command/pom.lux b/stdlib/source/test/aedifex/command/pom.lux index 1bb098de0..cd0eed8e9 100644 --- a/stdlib/source/test/aedifex/command/pom.lux +++ b/stdlib/source/test/aedifex/command/pom.lux @@ -33,7 +33,7 @@ (<| (_.covering /._) (do random.monad [sample @profile.random - #let [fs (file.mock (:: file.system separator))]] + #let [fs (file.mock (:: file.default separator))]] (wrap (do {@ promise.monad} [outcome (/.do! fs sample)] (case outcome diff --git a/stdlib/source/test/aedifex/input.lux b/stdlib/source/test/aedifex/input.lux index 39a71eb81..50b99a218 100644 --- a/stdlib/source/test/aedifex/input.lux +++ b/stdlib/source/test/aedifex/input.lux @@ -34,7 +34,7 @@ (do {@ random.monad} [expected (:: @ map (set@ #//.parents (list)) @profile.random) #let [fs (: (file.System Promise) - (file.mock (:: file.system separator)))]] + (file.mock (:: file.default separator)))]] (wrap (do promise.monad [verdict (do //action.monad [file (: (Promise (Try (File Promise))) diff --git a/stdlib/source/test/lux/control/parser/binary.lux b/stdlib/source/test/lux/control/parser/binary.lux index 11875d19f..98b8bab90 100644 --- a/stdlib/source/test/lux/control/parser/binary.lux +++ b/stdlib/source/test/lux/control/parser/binary.lux @@ -100,7 +100,7 @@ random.nat random.int random.rev - random.frac + random.safe-frac ..random-text ..random-name ..random-name @@ -213,8 +213,17 @@ [/.bit format.bit random.bit bit.equivalence] [/.nat format.nat random.nat n.equivalence] [/.int format.int random.int int.equivalence] - [/.rev format.rev random.rev rev.equivalence] - [/.frac format.frac random.frac frac.equivalence])) + [/.rev format.rev random.rev rev.equivalence])) + (do {@ random.monad} + [expected random.frac] + (_.cover [/.frac] + (|> expected + (format.run format.frac) + (/.run /.frac) + (!expect (^multi (#try.Success actual) + (or (:: frac.equivalence = expected actual) + (and (frac.not-a-number? expected) + (frac.not-a-number? actual)))))))) (do {@ random.monad} [expected (:: @ map (|>> (i64.and (i64.mask /.size/8)) (n.max 2)) diff --git a/stdlib/source/test/lux/data/collection/sequence.lux b/stdlib/source/test/lux/data/collection/sequence.lux index f47629d70..3cd41c4b2 100644 --- a/stdlib/source/test/lux/data/collection/sequence.lux +++ b/stdlib/source/test/lux/data/collection/sequence.lux @@ -1,102 +1,116 @@ (.module: [lux #* - ["%" data/text/format (#+ format)] ["_" test (#+ Test)] [abstract - comonad + [comonad (#+)] [functor (#+)] [monad (#+ do)] - ["." enum]] + [equivalence (#+ Equivalence)] + ["." enum] + {[0 #spec] + [/ + ["$." functor] + ["$." comonad]]}] [data - ["." maybe] [number - ["n" nat ("#@." decimal)]] - ["." text ("#@." monoid)] + ["n" nat]] + ["." text + ["%" format (#+ format)]] [collection - ["." list]]] + ["." list ("#@." functor)]]] [math - ["r" random]]] + ["." random]]] {1 ["." /]}) +(structure: (equivalence super) + (All [a] (-> (Equivalence a) (Equivalence (/.Sequence a)))) + + (def: (= reference subject) + (:: (list.equivalence super) = + (/.take 100 reference) + (/.take 100 subject)))) + (def: #export test Test - (<| (_.context (%.name (name-of /.Sequence))) - (do {@ r.monad} - [size (|> r.nat (:: @ map (|>> (n.% 100) (n.max 2)))) - offset (|> r.nat (:: @ map (n.% 100))) - factor (|> r.nat (:: @ map (|>> (n.% 100) (n.max 2)))) - elem r.nat - cycle-seed (r.list size r.nat) - cycle-sample-idx (|> r.nat (:: @ map (n.% 1000))) - #let [(^open "list@.") (list.equivalence n.equivalence) - sample0 (/.iterate inc 0) - sample1 (/.iterate inc offset)]] + (<| (_.covering /._) + (_.with-cover [/.Sequence]) + (let [(^open "list@.") (list.equivalence n.equivalence)]) + (do {@ random.monad} + [repeated random.nat + index (:: @ map (n.% 100) random.nat) + size (:: @ map (|>> (n.% 10) inc) random.nat) + offset (:: @ map (n.% 100) random.nat) + cycle-start random.nat + cycle-next (random.list size random.nat)] ($_ _.and - (_.test "Can move along a sequence and take slices off it." - (and (and (list@= (enum.range n.enum 0 (dec size)) - (/.take size sample0)) - (list@= (enum.range n.enum offset (dec (n.+ offset size))) - (/.take size (/.drop offset sample0))) - (let [[drops takes] (/.split size sample0)] - (and (list@= (enum.range n.enum 0 (dec size)) - drops) - (list@= (enum.range n.enum size (dec (n.* 2 size))) - (/.take size takes))))) - (and (list@= (enum.range n.enum 0 (dec size)) - (/.take-while (n.< size) sample0)) - (list@= (enum.range n.enum offset (dec (n.+ offset size))) - (/.take-while (n.< (n.+ offset size)) - (/.drop-while (n.< offset) sample0))) - (let [[drops takes] (/.split-while (n.< size) sample0)] - (and (list@= (enum.range n.enum 0 (dec size)) - drops) - (list@= (enum.range n.enum size (dec (n.* 2 size))) - (/.take-while (n.< (n.* 2 size)) takes))))) - )) - (_.test "Can repeat any element and infinite number of times." - (n.= elem (/.nth offset (/.repeat elem)))) - (_.test "Can obtain the head & tail of a sequence." - (and (n.= offset (/.head sample1)) - (list@= (enum.range n.enum (inc offset) (n.+ offset size)) - (/.take size (/.tail sample1))))) - (_.test "Can filter sequences." - (and (n.= (n.* 2 offset) - (/.nth offset - (/.filter n.even? sample0))) - (let [[evens odds] (/.partition n.even? (/.iterate inc 0))] - (and (n.= (n.* 2 offset) - (/.nth offset evens)) - (n.= (inc (n.* 2 offset)) - (/.nth offset odds)))))) - (_.test "Functor goes over 'all' elements in a sequence." - (let [(^open "/@.") /.functor - there (/@map (n.* factor) sample0) - back-again (/@map (n./ factor) there)] - (and (not (list@= (/.take size sample0) - (/.take size there))) - (list@= (/.take size sample0) - (/.take size back-again))))) - (_.test "CoMonad produces a value for every element in a sequence." - (let [(^open "/@.") /.functor] - (list@= (/.take size (/@map (n.* factor) sample1)) - (/.take size - (be /.comonad - [inputs sample1] - (n.* factor (/.head inputs))))))) - (_.test "'unfold' generalizes 'iterate'." - (let [(^open "/@.") /.functor - (^open "list@.") (list.equivalence text.equivalence)] - (list@= (/.take size - (/@map n@encode (/.iterate inc offset))) - (/.take size - (/.unfold (function (_ n) [(inc n) (n@encode n)]) - offset))))) - (_.test "Can cycle over the same elements as an infinite sequence." - (|> (/.cycle cycle-seed) - maybe.assume - (/.nth cycle-sample-idx) - (n.= (|> cycle-seed - (list.nth (n.% size cycle-sample-idx)) - maybe.assume)))) + (_.with-cover [/.functor] + ($functor.spec /.repeat ..equivalence /.functor)) + (_.with-cover [/.comonad] + ($comonad.spec /.repeat ..equivalence /.comonad)) + + (_.cover [/.iterate /.nth] + (n.= (n.+ offset index) + (/.nth index (/.iterate inc offset)))) + (_.cover [/.repeat] + (n.= repeated + (/.nth index (/.repeat repeated)))) + (_.cover [/.take] + (list@= (enum.range n.enum offset (dec (n.+ size offset))) + (/.take size (/.iterate inc offset)))) + (_.cover [/.drop] + (list@= (enum.range n.enum offset (dec (n.+ size offset))) + (/.take size (/.drop offset (/.iterate inc 0))))) + (_.cover [/.split] + (let [[drops takes] (/.split size (/.iterate inc 0))] + (and (list@= (enum.range n.enum 0 (dec size)) + drops) + (list@= (enum.range n.enum size (dec (n.* 2 size))) + (/.take size takes))))) + (_.cover [/.take-while] + (list@= (enum.range n.enum 0 (dec size)) + (/.take-while (n.< size) (/.iterate inc 0)))) + (_.cover [/.drop-while] + (list@= (enum.range n.enum offset (dec (n.+ size offset))) + (/.take-while (n.< (n.+ size offset)) + (/.drop-while (n.< offset) (/.iterate inc 0))))) + (_.cover [/.split-while] + (let [[drops takes] (/.split-while (n.< size) (/.iterate inc 0))] + (and (list@= (enum.range n.enum 0 (dec size)) + drops) + (list@= (enum.range n.enum size (dec (n.* 2 size))) + (/.take-while (n.< (n.* 2 size)) takes))))) + (_.cover [/.head] + (n.= offset + (/.head (/.iterate inc offset)))) + (_.cover [/.tail] + (list@= (enum.range n.enum (inc offset) (n.+ size offset)) + (/.take size (/.tail (/.iterate inc offset))))) + (_.cover [/.filter] + (list@= (list@map (n.* 2) (enum.range n.enum 0 (dec size))) + (/.take size (/.filter n.even? (/.iterate inc 0))))) + (_.cover [/.partition] + (let [[evens odds] (/.partition n.even? (/.iterate inc 0))] + (and (n.= (n.* 2 offset) + (/.nth offset evens)) + (n.= (inc (n.* 2 offset)) + (/.nth offset odds))))) + (_.cover [/.unfold] + (let [(^open "/@.") /.functor + (^open "list@.") (list.equivalence text.equivalence)] + (list@= (/.take size + (/@map %.nat (/.iterate inc offset))) + (/.take size + (/.unfold (function (_ n) [(inc n) (%.nat n)]) + offset))))) + (_.cover [/.cycle] + (let [cycle (list& cycle-start cycle-next)] + (list@= (list.concat (list.repeat size cycle)) + (/.take (n.* size (list.size cycle)) + (/.cycle [cycle-start cycle-next]))))) + (_.cover [/.^sequence&] + (let [(/.^sequence& first second third next) (/.iterate inc offset)] + (and (n.= offset first) + (n.= (n.+ 1 offset) second) + (n.= (n.+ 2 offset) third)))) )))) diff --git a/stdlib/source/test/lux/world/file.lux b/stdlib/source/test/lux/world/file.lux index 9dc1fb2e2..a1146fe56 100644 --- a/stdlib/source/test/lux/world/file.lux +++ b/stdlib/source/test/lux/world/file.lux @@ -39,9 +39,9 @@ result (promise.future (do (try.with io.monad) [#let [check-existence! (: (IO (Try Bit)) - (try.lift io.monad (/.exists? io.monad /.system path)))] + (try.lift io.monad (/.exists? io.monad /.default path)))] pre! check-existence! - file (!.use (:: /.system create-file) path) + file (!.use (:: /.default create-file) path) post! check-existence! _ (!.use (:: file delete) []) remains? check-existence!] @@ -57,7 +57,7 @@ [#let [path (format "temp_file_" (%.nat number))] result (promise.future (do (try.with io.monad) - [file (!.use (:: /.system create-file) path) + [file (!.use (:: /.default create-file) path) _ (!.use (:: file over-write) data) content (!.use (:: file content) []) _ (!.use (:: file delete) [])] @@ -84,7 +84,7 @@ [#let [path "temp_file_2"] result (promise.future (do (try.with io.monad) - [file (!.use (:: /.system create-file) path) + [file (!.use (:: /.default create-file) path) _ (!.use (:: file over-write) dataL) read-size (!.use (:: file size) []) _ (!.use (:: file delete) [])] @@ -95,7 +95,7 @@ [#let [path "temp_file_3"] result (promise.future (do (try.with io.monad) - [file (!.use (:: /.system create-file) path) + [file (!.use (:: /.default create-file) path) _ (!.use (:: file over-write) dataL) _ (!.use (:: file append) dataR) content (!.use (:: file content) []) @@ -115,9 +115,9 @@ result (promise.future (do (try.with io.monad) [#let [check-existence! (: (IO (Try Bit)) - (try.lift io.monad (/.exists? io.monad /.system path)))] + (try.lift io.monad (/.exists? io.monad /.default path)))] pre! check-existence! - dir (!.use (:: /.system create-directory) path) + dir (!.use (:: /.default create-directory) path) post! check-existence! _ (!.use (:: dir discard) []) remains? check-existence!] @@ -131,8 +131,8 @@ dir-path "temp_dir_5"] result (promise.future (do (try.with io.monad) - [dir (!.use (:: /.system create-directory) dir-path) - file (!.use (:: /.system create-file) (format dir-path "/" file-path)) + [dir (!.use (:: /.default create-directory) dir-path) + file (!.use (:: /.default create-file) (format dir-path "/" file-path)) _ (!.use (:: file over-write) dataL) read-size (!.use (:: file size) []) _ (!.use (:: file delete) []) @@ -146,12 +146,12 @@ inner-dir-path "inner_temp_dir_6"] result (promise.future (do (try.with io.monad) - [dir (!.use (:: /.system create-directory) dir-path) + [dir (!.use (:: /.default create-directory) dir-path) pre-files (!.use (:: dir files) []) pre-directories (!.use (:: dir directories) []) - file (!.use (:: /.system create-file) (format dir-path "/" file-path)) - inner-dir (!.use (:: /.system create-directory) (format dir-path "/" inner-dir-path)) + file (!.use (:: /.default create-file) (format dir-path "/" file-path)) + inner-dir (!.use (:: /.default create-directory) (format dir-path "/" inner-dir-path)) post-files (!.use (:: dir files) []) post-directories (!.use (:: dir directories) []) @@ -168,7 +168,7 @@ [#let [path "temp_file_7"] result (promise.future (do (try.with io.monad) - [file (!.use (:: /.system create-file) path) + [file (!.use (:: /.default create-file) path) _ (!.use (:: file over-write) dataL) _ (!.use (:: file modify) new-modified) current-modified (!.use (:: file last-modified) []) @@ -182,9 +182,9 @@ result (promise.future (do (try.with io.monad) [#let [check-existence! (: (-> Path (IO (Try Bit))) - (|>> (/.exists? io.monad /.system) + (|>> (/.exists? io.monad /.default) (try.lift io.monad)))] - file0 (!.use (:: /.system create-file) path0) + file0 (!.use (:: /.default create-file) path0) _ (!.use (:: file0 over-write) dataL) pre! (check-existence! path0) file1 (: (IO (Try (File IO))) ## TODO: Remove : |