From 1d7a328afcb649fa0a69f6df4bd7b1ca6aa8a59c Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Fri, 24 Mar 2017 17:38:39 -0400 Subject: - Moved lux/random to lux/math/random. - Moved lux/math/ratio to lux/number/ratio. - Moved lux/math/complex to lux/number/complex. --- stdlib/source/lux/data/number/complex.lux | 331 ++++++++++++++++++++++++++++++ stdlib/source/lux/data/number/ratio.lux | 158 ++++++++++++++ stdlib/source/lux/math/complex.lux | 331 ------------------------------ stdlib/source/lux/math/random.lux | 303 +++++++++++++++++++++++++++ stdlib/source/lux/math/ratio.lux | 158 -------------- stdlib/source/lux/random.lux | 302 --------------------------- stdlib/source/lux/test.lux | 2 +- 7 files changed, 793 insertions(+), 792 deletions(-) create mode 100644 stdlib/source/lux/data/number/complex.lux create mode 100644 stdlib/source/lux/data/number/ratio.lux delete mode 100644 stdlib/source/lux/math/complex.lux create mode 100644 stdlib/source/lux/math/random.lux delete mode 100644 stdlib/source/lux/math/ratio.lux delete mode 100644 stdlib/source/lux/random.lux (limited to 'stdlib/source') diff --git a/stdlib/source/lux/data/number/complex.lux b/stdlib/source/lux/data/number/complex.lux new file mode 100644 index 000000000..87b1a7d18 --- /dev/null +++ b/stdlib/source/lux/data/number/complex.lux @@ -0,0 +1,331 @@ +(;module: {#;doc "Complex arithmetic."} + lux + (lux [math] + (control eq + [ord] + number + codec + monad) + (data [number "r/" Number Codec] + [text "Text/" Monoid] + text/format + error + maybe + (coll [list "List/" Monad])) + [compiler] + (macro [ast] + ["s" syntax #+ syntax: Syntax]))) + +## Based on org.apache.commons.math4.complex.Complex +## https://github.com/apache/commons-math/blob/master/src/main/java/org/apache/commons/math4/complex/Complex.java + +(type: #export Complex + {#real Real + #imaginary Real}) + +(syntax: #export (complex real [?imaginary (s;opt s;any)]) + {#;doc (doc "Complex literals." + (complex real imaginary) + "The imaginary part can be omitted if it's 0." + (complex real))} + (wrap (list (` {#;;real (~ real) + #;;imaginary (~ (default (' 0.0) + ?imaginary))})))) + +(def: #export i Complex (complex 0.0 1.0)) + +(def: #export one Complex (complex 1.0 0.0)) + +(def: #export zero Complex (complex 0.0 0.0)) + +(def: #export (not-a-number? complex) + (or (number;not-a-number? (get@ #real complex)) + (number;not-a-number? (get@ #imaginary complex)))) + +(def: #export (c.= param input) + (-> Complex Complex Bool) + (and (r.= (get@ #real param) + (get@ #real input)) + (r.= (get@ #imaginary param) + (get@ #imaginary input)))) + +(do-template [ ] + [(def: #export ( param input) + (-> Complex Complex Complex) + {#real ( (get@ #real param) + (get@ #real input)) + #imaginary ( (get@ #imaginary param) + (get@ #imaginary input))})] + + [c.+ r.+] + [c.- r.-] + ) + +(struct: #export _ (Eq Complex) + (def: = c.=)) + +(def: #export c.negate + (-> Complex Complex) + (|>. (update@ #real r/negate) + (update@ #imaginary r/negate))) + +(def: #export c.signum + (-> Complex Complex) + (|>. (update@ #real r/signum) + (update@ #imaginary r/signum))) + +(def: #export conjugate + (-> Complex Complex) + (update@ #imaginary r/negate)) + +(def: #export (c.*' param input) + (-> Real Complex Complex) + {#real (r.* param + (get@ #real input)) + #imaginary (r.* param + (get@ #imaginary input))}) + +(def: #export (c.* param input) + (-> Complex Complex Complex) + {#real (r.- (r.* (get@ #imaginary param) + (get@ #imaginary input)) + (r.* (get@ #real param) + (get@ #real input))) + #imaginary (r.+ (r.* (get@ #real param) + (get@ #imaginary input)) + (r.* (get@ #imaginary param) + (get@ #real input)))}) + +(def: #export (c./ param input) + (-> Complex Complex Complex) + (let [(^slots [#real #imaginary]) param] + (if (r.< (r/abs imaginary) + (r/abs real)) + (let [quot (r./ imaginary real) + denom (|> real (r.* quot) (r.+ imaginary))] + {#real (|> (get@ #real input) (r.* quot) (r.+ (get@ #imaginary input)) (r./ denom)) + #imaginary (|> (get@ #imaginary input) (r.* quot) (r.- (get@ #real input)) (r./ denom))}) + (let [quot (r./ real imaginary) + denom (|> imaginary (r.* quot) (r.+ real))] + {#real (|> (get@ #imaginary input) (r.* quot) (r.+ (get@ #real input)) (r./ denom)) + #imaginary (|> (get@ #imaginary input) (r.- (r.* quot (get@ #real input))) (r./ denom))})))) + +(def: #export (c./' param subject) + (-> Real Complex Complex) + (let [(^slots [#real #imaginary]) subject] + {#real (r./ param real) + #imaginary (r./ param imaginary)})) + +(def: #export (c.% param input) + (-> Complex Complex Complex) + (let [scaled (c./ param input) + quotient (|> scaled + (update@ #real math;floor) + (update@ #imaginary math;floor))] + (c.- (c.* quotient param) + input))) + +(def: #export (cos subject) + (-> Complex Complex) + (let [(^slots [#real #imaginary]) subject] + {#real (r.* (math;cosh imaginary) + (math;cos real)) + #imaginary (r.* (math;sinh imaginary) + (r/negate (math;sin real)))})) + +(def: #export (cosh subject) + (-> Complex Complex) + (let [(^slots [#real #imaginary]) subject] + {#real (r.* (math;cos imaginary) + (math;cosh real)) + #imaginary (r.* (math;sin imaginary) + (math;sinh real))})) + +(def: #export (sin subject) + (-> Complex Complex) + (let [(^slots [#real #imaginary]) subject] + {#real (r.* (math;cosh imaginary) + (math;sin real)) + #imaginary (r.* (math;sinh imaginary) + (math;cos real))})) + +(def: #export (sinh subject) + (-> Complex Complex) + (let [(^slots [#real #imaginary]) subject] + {#real (r.* (math;cos imaginary) + (math;sinh real)) + #imaginary (r.* (math;sin imaginary) + (math;cosh real))})) + +(def: #export (tan subject) + (-> Complex Complex) + (let [(^slots [#real #imaginary]) subject + r2 (r.* 2.0 real) + i2 (r.* 2.0 imaginary) + d (r.+ (math;cos r2) (math;cosh i2))] + {#real (r./ d (math;sin r2)) + #imaginary (r./ d (math;sinh i2))})) + +(def: #export (tanh subject) + (-> Complex Complex) + (let [(^slots [#real #imaginary]) subject + r2 (r.* 2.0 real) + i2 (r.* 2.0 imaginary) + d (r.+ (math;cosh r2) (math;cos i2))] + {#real (r./ d (math;sinh r2)) + #imaginary (r./ d (math;sin i2))})) + +(def: #export (c.abs subject) + (-> Complex Complex) + (let [(^slots [#real #imaginary]) subject] + (complex (if (r.< (r/abs imaginary) + (r/abs real)) + (if (r.= 0.0 imaginary) + (r/abs real) + (let [q (r./ imaginary real)] + (r.* (math;root2 (r.+ 1.0 (r.* q q))) + (r/abs imaginary)))) + (if (r.= 0.0 real) + (r/abs imaginary) + (let [q (r./ real imaginary)] + (r.* (math;root2 (r.+ 1.0 (r.* q q))) + (r/abs real)))) + )))) + +(struct: #export _ (Number Complex) + (def: + c.+) + (def: - c.-) + (def: * c.*) + (def: / c./) + (def: % c.%) + (def: (negate x) + (|> x + (update@ #real r/negate) + (update@ #imaginary r/negate))) + (def: abs c.abs) + (def: (signum x) + (|> x + (update@ #real r/signum) + (update@ #imaginary r/signum)))) + +(def: #export (exp subject) + (-> Complex Complex) + (let [(^slots [#real #imaginary]) subject + r-exp (math;exp real)] + {#real (r.* r-exp (math;cos imaginary)) + #imaginary (r.* r-exp (math;sin imaginary))})) + +(def: #export (log subject) + (-> Complex Complex) + (let [(^slots [#real #imaginary]) subject] + {#real (|> subject c.abs (get@ #real) math;log) + #imaginary (math;atan2 real imaginary)})) + +(do-template [ ] + [(def: #export ( param input) + (-> Complex Complex) + (|> input log ( param) exp))] + + [pow Complex c.*] + [pow' Real c.*'] + ) + +(def: (copy-sign sign magnitude) + (-> Real Real Real) + (r.* (r/signum sign) magnitude)) + +(def: #export (root2 (^@ input (^slots [#real #imaginary]))) + (-> Complex Complex) + (let [t (|> input c.abs (get@ #real) (r.+ (r/abs real)) (r./ 2.0) math;root2)] + (if (r.>= 0.0 real) + {#real t + #imaginary (r./ (r.* 2.0 t) + imaginary)} + {#real (r./ (r.* 2.0 t) + (r/abs imaginary)) + #imaginary (r.* t (copy-sign imaginary 1.0))}))) + +(def: #export (root2-1z input) + (-> Complex Complex) + (|> (complex 1.0) (c.- (c.* input input)) root2)) + +(def: #export (reciprocal (^slots [#real #imaginary])) + (-> Complex Complex) + (if (r.< (r/abs imaginary) + (r/abs real)) + (let [q (r./ imaginary real) + scale (r./ (|> real (r.* q) (r.+ imaginary)) + 1.0)] + {#real (r.* q scale) + #imaginary (r/negate scale)}) + (let [q (r./ real imaginary) + scale (r./ (|> imaginary (r.* q) (r.+ real)) + 1.0)] + {#real scale + #imaginary (|> scale r/negate (r.* q))}))) + +(def: #export (acos input) + (-> Complex Complex) + (|> input + (c.+ (|> input root2-1z (c.* i))) + log + (c.* (c.negate i)))) + +(def: #export (asin input) + (-> Complex Complex) + (|> input + root2-1z + (c.+ (c.* i input)) + log + (c.* (c.negate i)))) + +(def: #export (atan input) + (-> Complex Complex) + (|> input + (c.+ i) + (c./ (c.- input i)) + log + (c.* (c./ (complex 2.0) i)))) + +(def: #export (argument (^slots [#real #imaginary])) + (-> Complex Real) + (math;atan2 real imaginary)) + +(def: #export (nth-roots nth input) + (-> Nat Complex (List Complex)) + (if (n.= +0 nth) + (list) + (let [r-nth (|> nth nat-to-int int-to-real) + nth-root-of-abs (|> input c.abs (get@ #real) (math;pow (r./ r-nth 1.0))) + nth-phi (|> input argument (r./ r-nth)) + slice (|> math;pi (r.* 2.0) (r./ r-nth))] + (|> (list;n.range +0 (n.dec nth)) + (List/map (lambda [nth'] + (let [inner (|> nth' nat-to-int int-to-real + (r.* slice) + (r.+ nth-phi)) + real (r.* nth-root-of-abs + (math;cos inner)) + imaginary (r.* nth-root-of-abs + (math;sin inner))] + {#real real + #imaginary imaginary}))))))) + +(struct: #export _ (Codec Text Complex) + (def: (encode (^slots [#real #imaginary])) + ($_ Text/append "(" (r/encode real) ", " (r/encode imaginary) ")")) + + (def: (decode input) + (case (do Monad + [input' (text;clip +1 (n.- +1 (text;size input)) input)] + (text;split-with "," input')) + #;None + (#;Left (Text/append "Wrong syntax for complex numbers: " input)) + + (#;Some [r' i']) + (do Monad + [r (r/decode (text;trim r')) + i (r/decode (text;trim i'))] + (wrap {#real r + #imaginary i})) + ))) diff --git a/stdlib/source/lux/data/number/ratio.lux b/stdlib/source/lux/data/number/ratio.lux new file mode 100644 index 000000000..fb86b1fed --- /dev/null +++ b/stdlib/source/lux/data/number/ratio.lux @@ -0,0 +1,158 @@ +(;module: {#;doc "Rational arithmetic."} + lux + (lux [math] + (control eq + [ord] + number + codec + monad) + (data [number "n/" Number Codec] + [text "Text/" Monoid] + text/format + error + [product]) + [compiler] + (macro [ast] + ["s" syntax #+ syntax: Syntax]))) + +(type: #export Ratio + {#numerator Nat + #denominator Nat}) + +(def: #hidden (normalize (^slots [#numerator #denominator])) + (-> Ratio Ratio) + (let [common (math;gcd numerator denominator)] + {#numerator (n./ common numerator) + #denominator (n./ common denominator)})) + +(def: #export (q.* param input) + (-> Ratio Ratio Ratio) + (normalize [(n.* (get@ #numerator param) + (get@ #numerator input)) + (n.* (get@ #denominator param) + (get@ #denominator input))])) + +(def: #export (q./ param input) + (-> Ratio Ratio Ratio) + (normalize [(n.* (get@ #denominator param) + (get@ #numerator input)) + (n.* (get@ #numerator param) + (get@ #denominator input))])) + +(def: #export (q.+ param input) + (-> Ratio Ratio Ratio) + (normalize [(n.+ (n.* (get@ #denominator input) + (get@ #numerator param)) + (n.* (get@ #denominator param) + (get@ #numerator input))) + (n.* (get@ #denominator param) + (get@ #denominator input))])) + +(def: #export (q.- param input) + (-> Ratio Ratio Ratio) + (normalize [(n.- (n.* (get@ #denominator input) + (get@ #numerator param)) + (n.* (get@ #denominator param) + (get@ #numerator input))) + (n.* (get@ #denominator param) + (get@ #denominator input))])) + +(def: #export (q.% param input) + (-> Ratio Ratio Ratio) + (let [quot (n./ (n.* (get@ #denominator input) + (get@ #numerator param)) + (n.* (get@ #denominator param) + (get@ #numerator input)))] + (q.- (update@ #numerator (n.* quot) param) + input))) + +(def: #export (q.= param input) + (-> Ratio Ratio Bool) + (and (n.= (get@ #numerator param) + (get@ #numerator input)) + (n.= (get@ #denominator param) + (get@ #denominator input)))) + +(do-template [ ] + [(def: #export ( param input) + (-> Ratio Ratio Bool) + (and ( (n.* (get@ #denominator input) + (get@ #numerator param)) + (n.* (get@ #denominator param) + (get@ #numerator input)))))] + + [q.< n.<] + [q.<= n.<=] + [q.> n.>] + [q.>= n.>=] + ) + +(do-template [ ] + [(def: #export ( left right) + (-> Ratio Ratio Ratio) + (if ( left right) + right + left))] + + [q.min q.<] + [q.max q.>] + ) + +(struct: #export _ (Eq Ratio) + (def: = q.=)) + +(struct: #export _ (ord;Ord Ratio) + (def: eq Eq) + (def: < q.<) + (def: <= q.<=) + (def: > q.>) + (def: >= q.>=)) + +(struct: #export _ (Number Ratio) + (def: + q.+) + (def: - q.-) + (def: * q.*) + (def: / q./) + (def: % q.%) + (def: (negate (^slots [#numerator #denominator])) + {#numerator denominator + #denominator numerator}) + (def: abs id) + (def: (signum x) + {#numerator +1 + #denominator +1})) + +(def: separator Text ":") + +(def: part-encode + (-> Nat Text) + (|>. n/encode (text;split +1) (default (undefined)) product;right)) + +(def: part-decode + (-> Text (Error Nat)) + (|>. (format "+") n/decode)) + +(struct: #export _ (Codec Text Ratio) + (def: (encode (^slots [#numerator #denominator])) + ($_ Text/append (part-encode numerator) separator (part-encode denominator))) + + (def: (decode input) + (case (text;split-with separator input) + (#;Some [num denom]) + (do Monad + [numerator (part-decode num) + denominator (part-decode denom)] + (wrap (normalize {#numerator numerator + #denominator denominator}))) + + #;None + (#;Left (Text/append "Invalid syntax for ratio: " input))))) + +(syntax: #export (ratio numerator [?denominator (s;opt s;any)]) + {#;doc (doc "Rational literals." + (ratio numerator denominator) + "The denominator can be omitted if it's 1." + (ratio numerator))} + (wrap (list (` (normalize {#;;numerator (~ numerator) + #;;denominator (~ (default (' +1) + ?denominator))}))))) diff --git a/stdlib/source/lux/math/complex.lux b/stdlib/source/lux/math/complex.lux deleted file mode 100644 index 87b1a7d18..000000000 --- a/stdlib/source/lux/math/complex.lux +++ /dev/null @@ -1,331 +0,0 @@ -(;module: {#;doc "Complex arithmetic."} - lux - (lux [math] - (control eq - [ord] - number - codec - monad) - (data [number "r/" Number Codec] - [text "Text/" Monoid] - text/format - error - maybe - (coll [list "List/" Monad])) - [compiler] - (macro [ast] - ["s" syntax #+ syntax: Syntax]))) - -## Based on org.apache.commons.math4.complex.Complex -## https://github.com/apache/commons-math/blob/master/src/main/java/org/apache/commons/math4/complex/Complex.java - -(type: #export Complex - {#real Real - #imaginary Real}) - -(syntax: #export (complex real [?imaginary (s;opt s;any)]) - {#;doc (doc "Complex literals." - (complex real imaginary) - "The imaginary part can be omitted if it's 0." - (complex real))} - (wrap (list (` {#;;real (~ real) - #;;imaginary (~ (default (' 0.0) - ?imaginary))})))) - -(def: #export i Complex (complex 0.0 1.0)) - -(def: #export one Complex (complex 1.0 0.0)) - -(def: #export zero Complex (complex 0.0 0.0)) - -(def: #export (not-a-number? complex) - (or (number;not-a-number? (get@ #real complex)) - (number;not-a-number? (get@ #imaginary complex)))) - -(def: #export (c.= param input) - (-> Complex Complex Bool) - (and (r.= (get@ #real param) - (get@ #real input)) - (r.= (get@ #imaginary param) - (get@ #imaginary input)))) - -(do-template [ ] - [(def: #export ( param input) - (-> Complex Complex Complex) - {#real ( (get@ #real param) - (get@ #real input)) - #imaginary ( (get@ #imaginary param) - (get@ #imaginary input))})] - - [c.+ r.+] - [c.- r.-] - ) - -(struct: #export _ (Eq Complex) - (def: = c.=)) - -(def: #export c.negate - (-> Complex Complex) - (|>. (update@ #real r/negate) - (update@ #imaginary r/negate))) - -(def: #export c.signum - (-> Complex Complex) - (|>. (update@ #real r/signum) - (update@ #imaginary r/signum))) - -(def: #export conjugate - (-> Complex Complex) - (update@ #imaginary r/negate)) - -(def: #export (c.*' param input) - (-> Real Complex Complex) - {#real (r.* param - (get@ #real input)) - #imaginary (r.* param - (get@ #imaginary input))}) - -(def: #export (c.* param input) - (-> Complex Complex Complex) - {#real (r.- (r.* (get@ #imaginary param) - (get@ #imaginary input)) - (r.* (get@ #real param) - (get@ #real input))) - #imaginary (r.+ (r.* (get@ #real param) - (get@ #imaginary input)) - (r.* (get@ #imaginary param) - (get@ #real input)))}) - -(def: #export (c./ param input) - (-> Complex Complex Complex) - (let [(^slots [#real #imaginary]) param] - (if (r.< (r/abs imaginary) - (r/abs real)) - (let [quot (r./ imaginary real) - denom (|> real (r.* quot) (r.+ imaginary))] - {#real (|> (get@ #real input) (r.* quot) (r.+ (get@ #imaginary input)) (r./ denom)) - #imaginary (|> (get@ #imaginary input) (r.* quot) (r.- (get@ #real input)) (r./ denom))}) - (let [quot (r./ real imaginary) - denom (|> imaginary (r.* quot) (r.+ real))] - {#real (|> (get@ #imaginary input) (r.* quot) (r.+ (get@ #real input)) (r./ denom)) - #imaginary (|> (get@ #imaginary input) (r.- (r.* quot (get@ #real input))) (r./ denom))})))) - -(def: #export (c./' param subject) - (-> Real Complex Complex) - (let [(^slots [#real #imaginary]) subject] - {#real (r./ param real) - #imaginary (r./ param imaginary)})) - -(def: #export (c.% param input) - (-> Complex Complex Complex) - (let [scaled (c./ param input) - quotient (|> scaled - (update@ #real math;floor) - (update@ #imaginary math;floor))] - (c.- (c.* quotient param) - input))) - -(def: #export (cos subject) - (-> Complex Complex) - (let [(^slots [#real #imaginary]) subject] - {#real (r.* (math;cosh imaginary) - (math;cos real)) - #imaginary (r.* (math;sinh imaginary) - (r/negate (math;sin real)))})) - -(def: #export (cosh subject) - (-> Complex Complex) - (let [(^slots [#real #imaginary]) subject] - {#real (r.* (math;cos imaginary) - (math;cosh real)) - #imaginary (r.* (math;sin imaginary) - (math;sinh real))})) - -(def: #export (sin subject) - (-> Complex Complex) - (let [(^slots [#real #imaginary]) subject] - {#real (r.* (math;cosh imaginary) - (math;sin real)) - #imaginary (r.* (math;sinh imaginary) - (math;cos real))})) - -(def: #export (sinh subject) - (-> Complex Complex) - (let [(^slots [#real #imaginary]) subject] - {#real (r.* (math;cos imaginary) - (math;sinh real)) - #imaginary (r.* (math;sin imaginary) - (math;cosh real))})) - -(def: #export (tan subject) - (-> Complex Complex) - (let [(^slots [#real #imaginary]) subject - r2 (r.* 2.0 real) - i2 (r.* 2.0 imaginary) - d (r.+ (math;cos r2) (math;cosh i2))] - {#real (r./ d (math;sin r2)) - #imaginary (r./ d (math;sinh i2))})) - -(def: #export (tanh subject) - (-> Complex Complex) - (let [(^slots [#real #imaginary]) subject - r2 (r.* 2.0 real) - i2 (r.* 2.0 imaginary) - d (r.+ (math;cosh r2) (math;cos i2))] - {#real (r./ d (math;sinh r2)) - #imaginary (r./ d (math;sin i2))})) - -(def: #export (c.abs subject) - (-> Complex Complex) - (let [(^slots [#real #imaginary]) subject] - (complex (if (r.< (r/abs imaginary) - (r/abs real)) - (if (r.= 0.0 imaginary) - (r/abs real) - (let [q (r./ imaginary real)] - (r.* (math;root2 (r.+ 1.0 (r.* q q))) - (r/abs imaginary)))) - (if (r.= 0.0 real) - (r/abs imaginary) - (let [q (r./ real imaginary)] - (r.* (math;root2 (r.+ 1.0 (r.* q q))) - (r/abs real)))) - )))) - -(struct: #export _ (Number Complex) - (def: + c.+) - (def: - c.-) - (def: * c.*) - (def: / c./) - (def: % c.%) - (def: (negate x) - (|> x - (update@ #real r/negate) - (update@ #imaginary r/negate))) - (def: abs c.abs) - (def: (signum x) - (|> x - (update@ #real r/signum) - (update@ #imaginary r/signum)))) - -(def: #export (exp subject) - (-> Complex Complex) - (let [(^slots [#real #imaginary]) subject - r-exp (math;exp real)] - {#real (r.* r-exp (math;cos imaginary)) - #imaginary (r.* r-exp (math;sin imaginary))})) - -(def: #export (log subject) - (-> Complex Complex) - (let [(^slots [#real #imaginary]) subject] - {#real (|> subject c.abs (get@ #real) math;log) - #imaginary (math;atan2 real imaginary)})) - -(do-template [ ] - [(def: #export ( param input) - (-> Complex Complex) - (|> input log ( param) exp))] - - [pow Complex c.*] - [pow' Real c.*'] - ) - -(def: (copy-sign sign magnitude) - (-> Real Real Real) - (r.* (r/signum sign) magnitude)) - -(def: #export (root2 (^@ input (^slots [#real #imaginary]))) - (-> Complex Complex) - (let [t (|> input c.abs (get@ #real) (r.+ (r/abs real)) (r./ 2.0) math;root2)] - (if (r.>= 0.0 real) - {#real t - #imaginary (r./ (r.* 2.0 t) - imaginary)} - {#real (r./ (r.* 2.0 t) - (r/abs imaginary)) - #imaginary (r.* t (copy-sign imaginary 1.0))}))) - -(def: #export (root2-1z input) - (-> Complex Complex) - (|> (complex 1.0) (c.- (c.* input input)) root2)) - -(def: #export (reciprocal (^slots [#real #imaginary])) - (-> Complex Complex) - (if (r.< (r/abs imaginary) - (r/abs real)) - (let [q (r./ imaginary real) - scale (r./ (|> real (r.* q) (r.+ imaginary)) - 1.0)] - {#real (r.* q scale) - #imaginary (r/negate scale)}) - (let [q (r./ real imaginary) - scale (r./ (|> imaginary (r.* q) (r.+ real)) - 1.0)] - {#real scale - #imaginary (|> scale r/negate (r.* q))}))) - -(def: #export (acos input) - (-> Complex Complex) - (|> input - (c.+ (|> input root2-1z (c.* i))) - log - (c.* (c.negate i)))) - -(def: #export (asin input) - (-> Complex Complex) - (|> input - root2-1z - (c.+ (c.* i input)) - log - (c.* (c.negate i)))) - -(def: #export (atan input) - (-> Complex Complex) - (|> input - (c.+ i) - (c./ (c.- input i)) - log - (c.* (c./ (complex 2.0) i)))) - -(def: #export (argument (^slots [#real #imaginary])) - (-> Complex Real) - (math;atan2 real imaginary)) - -(def: #export (nth-roots nth input) - (-> Nat Complex (List Complex)) - (if (n.= +0 nth) - (list) - (let [r-nth (|> nth nat-to-int int-to-real) - nth-root-of-abs (|> input c.abs (get@ #real) (math;pow (r./ r-nth 1.0))) - nth-phi (|> input argument (r./ r-nth)) - slice (|> math;pi (r.* 2.0) (r./ r-nth))] - (|> (list;n.range +0 (n.dec nth)) - (List/map (lambda [nth'] - (let [inner (|> nth' nat-to-int int-to-real - (r.* slice) - (r.+ nth-phi)) - real (r.* nth-root-of-abs - (math;cos inner)) - imaginary (r.* nth-root-of-abs - (math;sin inner))] - {#real real - #imaginary imaginary}))))))) - -(struct: #export _ (Codec Text Complex) - (def: (encode (^slots [#real #imaginary])) - ($_ Text/append "(" (r/encode real) ", " (r/encode imaginary) ")")) - - (def: (decode input) - (case (do Monad - [input' (text;clip +1 (n.- +1 (text;size input)) input)] - (text;split-with "," input')) - #;None - (#;Left (Text/append "Wrong syntax for complex numbers: " input)) - - (#;Some [r' i']) - (do Monad - [r (r/decode (text;trim r')) - i (r/decode (text;trim i'))] - (wrap {#real r - #imaginary i})) - ))) diff --git a/stdlib/source/lux/math/random.lux b/stdlib/source/lux/math/random.lux new file mode 100644 index 000000000..e828cb715 --- /dev/null +++ b/stdlib/source/lux/math/random.lux @@ -0,0 +1,303 @@ +(;module: {#;doc "Pseudo-random number generation (PRNG) algorithms."} + [lux #- list] + (lux (control functor + applicative + monad + hash) + (data [bit] + [char] + [text "Text/" Monoid] + text/format + [product] + [number] + (number ["r" ratio] + ["c" complex]) + (coll [list "List/" Fold] + ["A" array] + ["D" dict] + ["Q" queue] + ["S" set] + ["ST" stack] + ["V" vector])) + )) + +## [Exports] +(type: #export #rec PRNG + {#;doc "An abstract way to represent any PRNG."} + (-> Unit [PRNG Nat])) + +(type: #export (Random a) + {#;doc "A producer of random values based on a PRNG."} + (-> PRNG [PRNG a])) + +(struct: #export _ (Functor Random) + (def: (map f fa) + (lambda [state] + (let [[state' a] (fa state)] + [state' (f a)])))) + +(struct: #export _ (Applicative Random) + (def: functor Functor) + + (def: (wrap a) + (lambda [state] + [state a])) + + (def: (apply ff fa) + (lambda [state] + (let [[state' f] (ff state) + [state'' a] (fa state')] + [state'' (f a)])))) + +(struct: #export _ (Monad Random) + (def: applicative Applicative) + + (def: (join ffa) + (lambda [state] + (let [[state' fa] (ffa state)] + (fa state'))))) + +(def: #export nat + (Random Nat) + (lambda [prng] + (let [[prng left] (prng []) + [prng right] (prng [])] + [prng (n.+ (bit;<< +32 left) + right)]))) + +(def: #export int + (Random Int) + (lambda [prng] + (let [[prng left] (prng []) + [prng right] (prng [])] + [prng (nat-to-int (n.+ (bit;<< +32 left) + right))]))) + +(def: #export bool + (Random Bool) + (lambda [prng] + (let [[prng output] (prng [])] + [prng (|> output (bit;& +1) (n.= +1))]))) + +(def: (bits n) + (-> Nat (Random Nat)) + (lambda [prng] + (let [[prng output] (prng [])] + [prng (bit;>>> (n.- n +64) output)]))) + +(def: #export real + (Random Real) + (do Monad + [left (bits +26) + right (bits +27)] + (wrap (|> right + (n.+ (bit;<< +27 left)) + nat-to-int + int-to-real + (r./ (|> +1 (bit;<< +53) nat-to-int int-to-real)))))) + +(def: #export deg + (Random Deg) + (:: Monad map real-to-deg real)) + +(def: #export char + (Random Char) + (do Monad + [base nat] + (wrap (char;char base)))) + +(def: #export (text' char-gen size) + (-> (Random Char) Nat (Random Text)) + (if (n.= +0 size) + (:: Monad wrap "") + (do Monad + [x char-gen + xs (text' char-gen (n.dec size))] + (wrap (Text/append (char;as-text x) xs))))) + +(def: #export (text size) + (-> Nat (Random Text)) + (text' char size)) + +(do-template [ ] + [(def: #export + (Random ) + (do Monad + [left + right ] + (wrap ( left right))))] + + [ratio r;Ratio r;ratio nat] + [complex c;Complex c;complex real] + ) + +(def: #export (seq left right) + {#;doc "Sequencing combinator."} + (All [a b] (-> (Random a) (Random b) (Random [a b]))) + (do Monad + [=left left + =right right] + (wrap [=left =right]))) + +(def: #export (alt left right) + {#;doc "Heterogeneous alternative combinator."} + (All [a b] (-> (Random a) (Random b) (Random (| a b)))) + (do Monad + [? bool] + (if ? + (do @ + [=left left] + (wrap (+0 =left))) + (do @ + [=right right] + (wrap (+1 =right)))))) + +(def: #export (either left right) + {#;doc "Homogeneous alternative combinator."} + (All [a] (-> (Random a) (Random a) (Random a))) + (do Monad + [? bool] + (if ? + left + right))) + +(def: #export (rec gen) + {#;doc "A combinator for producing recursive random generators."} + (All [a] (-> (-> (Random a) (Random a)) (Random a))) + (lambda [state] + (let [gen' (gen (rec gen))] + (gen' state)))) + +(def: #export (filter pred gen) + {#;doc "Retries the generator until the output satisfies a predicate."} + (All [a] (-> (-> a Bool) (Random a) (Random a))) + (do Monad + [sample gen] + (if (pred sample) + (wrap sample) + (filter pred gen)))) + +(def: #export (maybe value-gen) + (All [a] (-> (Random a) (Random (Maybe a)))) + (do Monad + [some? bool] + (if some? + (do @ + [value value-gen] + (wrap (#;Some value))) + (wrap #;None)))) + +(do-template [ ] + [(def: #export ( size value-gen) + (All [a] (-> Nat (Random a) (Random ( a)))) + (if (n.> +0 size) + (do Monad + [x value-gen + xs ( (n.dec size) value-gen)] + (wrap ( x xs))) + (:: Monad wrap )))] + + [list List (;list) #;Cons] + [vector V;Vector V;empty V;add] + ) + +(do-template [ ] + [(def: #export ( size value-gen) + (All [a] (-> Nat (Random a) (Random ( a)))) + (do Monad + [values (list size value-gen)] + (wrap (|> values ))))] + + [array A;Array A;from-list] + [queue Q;Queue Q;from-list] + [stack ST;Stack (List/fold ST;push ST;empty)] + ) + +(def: #export (set Hash size value-gen) + (All [a] (-> (Hash a) Nat (Random a) (Random (S;Set a)))) + (if (n.> +0 size) + (do Monad + [xs (set Hash (n.dec size) value-gen)] + (loop [_ []] + (do @ + [x value-gen + #let [xs+ (S;add x xs)]] + (if (n.= size (S;size xs+)) + (wrap xs+) + (recur []))))) + (:: Monad wrap (S;new Hash)))) + +(def: #export (dict Hash size key-gen value-gen) + (All [k v] (-> (Hash k) Nat (Random k) (Random v) (Random (D;Dict k v)))) + (if (n.> +0 size) + (do Monad + [kv (dict Hash (n.dec size) key-gen value-gen)] + (loop [_ []] + (do @ + [k key-gen + v value-gen + #let [kv+ (D;put k v kv)]] + (if (n.= size (D;size kv+)) + (wrap kv+) + (recur []))))) + (:: Monad wrap (D;new Hash)))) + +(def: #export (run prng calc) + (All [a] (-> PRNG (Random a) [PRNG a])) + (calc prng)) + +## [PRNGs] +## PCG32 http://www.pcg-random.org/ +## Based on this Java implementation: https://github.com/alexeyr/pcg-java + +(def: pcg-32-magic-mult Nat +6364136223846793005) + +(def: #export (pcg-32 [inc seed]) + {#;doc "An implementation of the PCG32 algorithm. + + For more information, please see: http://www.pcg-random.org/"} + (-> [Nat Nat] PRNG) + (lambda [_] + (let [seed' (|> seed (n.* pcg-32-magic-mult) (n.+ inc)) + xor-shifted (|> seed (bit;>>> +18) (bit;^ seed) (bit;>>> +27)) + rot (|> seed (bit;>>> +59))] + [(pcg-32 [inc seed']) (bit;rotate-right rot xor-shifted)] + ))) + +## Xoroshiro128+ http://xoroshiro.di.unimi.it/ +(def: #export (xoroshiro-128+ [s0 s1]) + {#;doc "An implementation of the Xoroshiro128+ algorithm. + + For more information, please see: http://xoroshiro.di.unimi.it/"} + (-> [Nat Nat] PRNG) + (lambda [_] + (let [result (n.+ s0 s1) + s01 (bit;^ s0 s1) + s0' (|> (bit;rotate-left +55 s0) + (bit;^ s01) + (bit;^ (bit;<< +14 s01))) + s1' (bit;rotate-left +36 s01)] + [(xoroshiro-128+ [s0' s1']) result]) + )) + +## [Values] +(def: (swap from to vec) + (All [a] (-> Nat Nat (V;Vector a) (V;Vector a))) + (V;put to (default (undefined) + (V;nth from vec)) + vec)) + +(def: #export (shuffle seed vector) + {#;doc "Shuffle a vector randomly based on a seed value."} + (All [a] (-> Nat (V;Vector a) (V;Vector a))) + (let [_size (V;size vector) + _shuffle (foldM Monad + (lambda [idx vec] + (do Monad + [rand nat] + (wrap (swap idx (n.% _size rand) vec)))) + vector + (list;n.range +0 (n.dec _size)))] + (|> _shuffle + (run (pcg-32 [+123 seed])) + product;right))) diff --git a/stdlib/source/lux/math/ratio.lux b/stdlib/source/lux/math/ratio.lux deleted file mode 100644 index fb86b1fed..000000000 --- a/stdlib/source/lux/math/ratio.lux +++ /dev/null @@ -1,158 +0,0 @@ -(;module: {#;doc "Rational arithmetic."} - lux - (lux [math] - (control eq - [ord] - number - codec - monad) - (data [number "n/" Number Codec] - [text "Text/" Monoid] - text/format - error - [product]) - [compiler] - (macro [ast] - ["s" syntax #+ syntax: Syntax]))) - -(type: #export Ratio - {#numerator Nat - #denominator Nat}) - -(def: #hidden (normalize (^slots [#numerator #denominator])) - (-> Ratio Ratio) - (let [common (math;gcd numerator denominator)] - {#numerator (n./ common numerator) - #denominator (n./ common denominator)})) - -(def: #export (q.* param input) - (-> Ratio Ratio Ratio) - (normalize [(n.* (get@ #numerator param) - (get@ #numerator input)) - (n.* (get@ #denominator param) - (get@ #denominator input))])) - -(def: #export (q./ param input) - (-> Ratio Ratio Ratio) - (normalize [(n.* (get@ #denominator param) - (get@ #numerator input)) - (n.* (get@ #numerator param) - (get@ #denominator input))])) - -(def: #export (q.+ param input) - (-> Ratio Ratio Ratio) - (normalize [(n.+ (n.* (get@ #denominator input) - (get@ #numerator param)) - (n.* (get@ #denominator param) - (get@ #numerator input))) - (n.* (get@ #denominator param) - (get@ #denominator input))])) - -(def: #export (q.- param input) - (-> Ratio Ratio Ratio) - (normalize [(n.- (n.* (get@ #denominator input) - (get@ #numerator param)) - (n.* (get@ #denominator param) - (get@ #numerator input))) - (n.* (get@ #denominator param) - (get@ #denominator input))])) - -(def: #export (q.% param input) - (-> Ratio Ratio Ratio) - (let [quot (n./ (n.* (get@ #denominator input) - (get@ #numerator param)) - (n.* (get@ #denominator param) - (get@ #numerator input)))] - (q.- (update@ #numerator (n.* quot) param) - input))) - -(def: #export (q.= param input) - (-> Ratio Ratio Bool) - (and (n.= (get@ #numerator param) - (get@ #numerator input)) - (n.= (get@ #denominator param) - (get@ #denominator input)))) - -(do-template [ ] - [(def: #export ( param input) - (-> Ratio Ratio Bool) - (and ( (n.* (get@ #denominator input) - (get@ #numerator param)) - (n.* (get@ #denominator param) - (get@ #numerator input)))))] - - [q.< n.<] - [q.<= n.<=] - [q.> n.>] - [q.>= n.>=] - ) - -(do-template [ ] - [(def: #export ( left right) - (-> Ratio Ratio Ratio) - (if ( left right) - right - left))] - - [q.min q.<] - [q.max q.>] - ) - -(struct: #export _ (Eq Ratio) - (def: = q.=)) - -(struct: #export _ (ord;Ord Ratio) - (def: eq Eq) - (def: < q.<) - (def: <= q.<=) - (def: > q.>) - (def: >= q.>=)) - -(struct: #export _ (Number Ratio) - (def: + q.+) - (def: - q.-) - (def: * q.*) - (def: / q./) - (def: % q.%) - (def: (negate (^slots [#numerator #denominator])) - {#numerator denominator - #denominator numerator}) - (def: abs id) - (def: (signum x) - {#numerator +1 - #denominator +1})) - -(def: separator Text ":") - -(def: part-encode - (-> Nat Text) - (|>. n/encode (text;split +1) (default (undefined)) product;right)) - -(def: part-decode - (-> Text (Error Nat)) - (|>. (format "+") n/decode)) - -(struct: #export _ (Codec Text Ratio) - (def: (encode (^slots [#numerator #denominator])) - ($_ Text/append (part-encode numerator) separator (part-encode denominator))) - - (def: (decode input) - (case (text;split-with separator input) - (#;Some [num denom]) - (do Monad - [numerator (part-decode num) - denominator (part-decode denom)] - (wrap (normalize {#numerator numerator - #denominator denominator}))) - - #;None - (#;Left (Text/append "Invalid syntax for ratio: " input))))) - -(syntax: #export (ratio numerator [?denominator (s;opt s;any)]) - {#;doc (doc "Rational literals." - (ratio numerator denominator) - "The denominator can be omitted if it's 1." - (ratio numerator))} - (wrap (list (` (normalize {#;;numerator (~ numerator) - #;;denominator (~ (default (' +1) - ?denominator))}))))) diff --git a/stdlib/source/lux/random.lux b/stdlib/source/lux/random.lux deleted file mode 100644 index 4cbc2b57b..000000000 --- a/stdlib/source/lux/random.lux +++ /dev/null @@ -1,302 +0,0 @@ -(;module: {#;doc "Pseudo-random number generation (PRNG) algorithms."} - [lux #- list] - (lux (control functor - applicative - monad - hash) - (data [bit] - [char] - [text "Text/" Monoid] - text/format - [product] - [number] - (coll [list "List/" Fold] - ["A" array] - ["D" dict] - ["Q" queue] - ["S" set] - ["ST" stack] - ["V" vector])) - (math ["r" ratio] - ["c" complex]))) - -## [Exports] -(type: #export #rec PRNG - {#;doc "An abstract way to represent any PRNG."} - (-> Unit [PRNG Nat])) - -(type: #export (Random a) - {#;doc "A producer of random values based on a PRNG."} - (-> PRNG [PRNG a])) - -(struct: #export _ (Functor Random) - (def: (map f fa) - (lambda [state] - (let [[state' a] (fa state)] - [state' (f a)])))) - -(struct: #export _ (Applicative Random) - (def: functor Functor) - - (def: (wrap a) - (lambda [state] - [state a])) - - (def: (apply ff fa) - (lambda [state] - (let [[state' f] (ff state) - [state'' a] (fa state')] - [state'' (f a)])))) - -(struct: #export _ (Monad Random) - (def: applicative Applicative) - - (def: (join ffa) - (lambda [state] - (let [[state' fa] (ffa state)] - (fa state'))))) - -(def: #export nat - (Random Nat) - (lambda [prng] - (let [[prng left] (prng []) - [prng right] (prng [])] - [prng (n.+ (bit;<< +32 left) - right)]))) - -(def: #export int - (Random Int) - (lambda [prng] - (let [[prng left] (prng []) - [prng right] (prng [])] - [prng (nat-to-int (n.+ (bit;<< +32 left) - right))]))) - -(def: #export bool - (Random Bool) - (lambda [prng] - (let [[prng output] (prng [])] - [prng (|> output (bit;& +1) (n.= +1))]))) - -(def: (bits n) - (-> Nat (Random Nat)) - (lambda [prng] - (let [[prng output] (prng [])] - [prng (bit;>>> (n.- n +64) output)]))) - -(def: #export real - (Random Real) - (do Monad - [left (bits +26) - right (bits +27)] - (wrap (|> right - (n.+ (bit;<< +27 left)) - nat-to-int - int-to-real - (r./ (|> +1 (bit;<< +53) nat-to-int int-to-real)))))) - -(def: #export deg - (Random Deg) - (:: Monad map real-to-deg real)) - -(def: #export char - (Random Char) - (do Monad - [base nat] - (wrap (char;char base)))) - -(def: #export (text' char-gen size) - (-> (Random Char) Nat (Random Text)) - (if (n.= +0 size) - (:: Monad wrap "") - (do Monad - [x char-gen - xs (text' char-gen (n.dec size))] - (wrap (Text/append (char;as-text x) xs))))) - -(def: #export (text size) - (-> Nat (Random Text)) - (text' char size)) - -(do-template [ ] - [(def: #export - (Random ) - (do Monad - [left - right ] - (wrap ( left right))))] - - [ratio r;Ratio r;ratio nat] - [complex c;Complex c;complex real] - ) - -(def: #export (seq left right) - {#;doc "Sequencing combinator."} - (All [a b] (-> (Random a) (Random b) (Random [a b]))) - (do Monad - [=left left - =right right] - (wrap [=left =right]))) - -(def: #export (alt left right) - {#;doc "Heterogeneous alternative combinator."} - (All [a b] (-> (Random a) (Random b) (Random (| a b)))) - (do Monad - [? bool] - (if ? - (do @ - [=left left] - (wrap (+0 =left))) - (do @ - [=right right] - (wrap (+1 =right)))))) - -(def: #export (either left right) - {#;doc "Homogeneous alternative combinator."} - (All [a] (-> (Random a) (Random a) (Random a))) - (do Monad - [? bool] - (if ? - left - right))) - -(def: #export (rec gen) - {#;doc "A combinator for producing recursive random generators."} - (All [a] (-> (-> (Random a) (Random a)) (Random a))) - (lambda [state] - (let [gen' (gen (rec gen))] - (gen' state)))) - -(def: #export (filter pred gen) - {#;doc "Retries the generator until the output satisfies a predicate."} - (All [a] (-> (-> a Bool) (Random a) (Random a))) - (do Monad - [sample gen] - (if (pred sample) - (wrap sample) - (filter pred gen)))) - -(def: #export (maybe value-gen) - (All [a] (-> (Random a) (Random (Maybe a)))) - (do Monad - [some? bool] - (if some? - (do @ - [value value-gen] - (wrap (#;Some value))) - (wrap #;None)))) - -(do-template [ ] - [(def: #export ( size value-gen) - (All [a] (-> Nat (Random a) (Random ( a)))) - (if (n.> +0 size) - (do Monad - [x value-gen - xs ( (n.dec size) value-gen)] - (wrap ( x xs))) - (:: Monad wrap )))] - - [list List (;list) #;Cons] - [vector V;Vector V;empty V;add] - ) - -(do-template [ ] - [(def: #export ( size value-gen) - (All [a] (-> Nat (Random a) (Random ( a)))) - (do Monad - [values (list size value-gen)] - (wrap (|> values ))))] - - [array A;Array A;from-list] - [queue Q;Queue Q;from-list] - [stack ST;Stack (List/fold ST;push ST;empty)] - ) - -(def: #export (set Hash size value-gen) - (All [a] (-> (Hash a) Nat (Random a) (Random (S;Set a)))) - (if (n.> +0 size) - (do Monad - [xs (set Hash (n.dec size) value-gen)] - (loop [_ []] - (do @ - [x value-gen - #let [xs+ (S;add x xs)]] - (if (n.= size (S;size xs+)) - (wrap xs+) - (recur []))))) - (:: Monad wrap (S;new Hash)))) - -(def: #export (dict Hash size key-gen value-gen) - (All [k v] (-> (Hash k) Nat (Random k) (Random v) (Random (D;Dict k v)))) - (if (n.> +0 size) - (do Monad - [kv (dict Hash (n.dec size) key-gen value-gen)] - (loop [_ []] - (do @ - [k key-gen - v value-gen - #let [kv+ (D;put k v kv)]] - (if (n.= size (D;size kv+)) - (wrap kv+) - (recur []))))) - (:: Monad wrap (D;new Hash)))) - -(def: #export (run prng calc) - (All [a] (-> PRNG (Random a) [PRNG a])) - (calc prng)) - -## [PRNGs] -## PCG32 http://www.pcg-random.org/ -## Based on this Java implementation: https://github.com/alexeyr/pcg-java - -(def: pcg-32-magic-mult Nat +6364136223846793005) - -(def: #export (pcg-32 [inc seed]) - {#;doc "An implementation of the PCG32 algorithm. - - For more information, please see: http://www.pcg-random.org/"} - (-> [Nat Nat] PRNG) - (lambda [_] - (let [seed' (|> seed (n.* pcg-32-magic-mult) (n.+ inc)) - xor-shifted (|> seed (bit;>>> +18) (bit;^ seed) (bit;>>> +27)) - rot (|> seed (bit;>>> +59))] - [(pcg-32 [inc seed']) (bit;rotate-right rot xor-shifted)] - ))) - -## Xoroshiro128+ http://xoroshiro.di.unimi.it/ -(def: #export (xoroshiro-128+ [s0 s1]) - {#;doc "An implementation of the Xoroshiro128+ algorithm. - - For more information, please see: http://xoroshiro.di.unimi.it/"} - (-> [Nat Nat] PRNG) - (lambda [_] - (let [result (n.+ s0 s1) - s01 (bit;^ s0 s1) - s0' (|> (bit;rotate-left +55 s0) - (bit;^ s01) - (bit;^ (bit;<< +14 s01))) - s1' (bit;rotate-left +36 s01)] - [(xoroshiro-128+ [s0' s1']) result]) - )) - -## [Values] -(def: (swap from to vec) - (All [a] (-> Nat Nat (V;Vector a) (V;Vector a))) - (V;put to (default (undefined) - (V;nth from vec)) - vec)) - -(def: #export (shuffle seed vector) - {#;doc "Shuffle a vector randomly based on a seed value."} - (All [a] (-> Nat (V;Vector a) (V;Vector a))) - (let [_size (V;size vector) - _shuffle (foldM Monad - (lambda [idx vec] - (do Monad - [rand nat] - (wrap (swap idx (n.% _size rand) vec)))) - vector - (list;n.range +0 (n.dec _size)))] - (|> _shuffle - (run (pcg-32 [+123 seed])) - product;right))) diff --git a/stdlib/source/lux/test.lux b/stdlib/source/lux/test.lux index d953b7d65..94a77d8cf 100644 --- a/stdlib/source/lux/test.lux +++ b/stdlib/source/lux/test.lux @@ -13,7 +13,7 @@ text/format [error #- fail "Error/" Monad]) [io #- run] - ["R" random])) + ["R" math/random])) ## [Host] (def: now -- cgit v1.2.3