(.module: [lux #* data/text/format ["_" test (#+ Test)] [control pipe codec [monad (#+ do Monad)] [equivalence (#+ Equivalence)] ["p" parser] {[0 #test] [/ ["$." equivalence] ["$." codec]]}] [data ["." error] ["." bit] ["." maybe] ["." text] [number ["." frac]] [collection [row (#+ row)] ["d" dictionary] ["." list]]] [macro [poly (#+ derived:)] ["." poly/equivalence] ["." poly/json]] [type ["." unit]] [math ["r" random (#+ Random)]] [time ["ti" instant] ["tda" date] ## ["tdu" duration] ]] [test [lux [time ["_." instant] ## ["_." duration] ["_." date]]]] {1 ["." / (#+ JSON)]} ) (def: #export json (Random JSON) (r.rec (function (_ json) (do r.monad [size (:: @ map (n/% 2) r.nat)] ($_ r.or (:: @ wrap []) r.bit r.frac (r.unicode size) (r.row size json) (r.dictionary text.hash size (r.unicode size) json) ))))) (type: Variant (#Bit Bit) (#Text Text) (#Frac Frac)) (type: #rec Recursive (#Number Frac) (#Addition Frac Recursive)) (type: Record {#bit Bit #frac Frac #text Text #maybe (Maybe Frac) #list (List Frac) #dictionary (d.Dictionary Text Frac) #variant Variant #tuple [Bit Frac Text] #recursive Recursive ## #instant ti.Instant ## #duration tdu.Duration #date tda.Date #grams (unit.Qty unit.Gram) }) (def: gen-recursive (Random Recursive) (r.rec (function (_ gen-recursive) (r.or r.frac (r.and r.frac gen-recursive))))) (derived: recursive-equivalence (poly/equivalence.equivalence Recursive)) (def: qty (All [unit] (Random (unit.Qty unit))) (|> r.int (:: r.monad map unit.in))) (def: gen-record (Random Record) (do r.monad [size (:: @ map (n/% 2) r.nat)] ($_ r.and r.bit r.frac (r.unicode size) (r.maybe r.frac) (r.list size r.frac) (r.dictionary text.hash size (r.unicode size) r.frac) ($_ r.or r.bit (r.unicode size) r.frac) ($_ r.and r.bit r.frac (r.unicode size)) gen-recursive ## _instant.instant ## _duration.duration _date.date qty ))) (derived: equivalence (poly/equivalence.equivalence Record)) (derived: codec (poly/json.codec Record)) (def: #export test Test (<| (_.context (%name (name-of /.JSON))) ($_ _.and ($equivalence.spec /.equivalence ..json) ($codec.spec /.equivalence /.codec ..json) (<| (_.context "Polytypism.") (<| (_.seed 14562075782602945288) ($codec.spec ..equivalence ..codec gen-record))) )))