(.require [library [lux (.except) [abstract [monad (.only do)] ["[0]" functor ["[1]T" \\test (.only Injection Comparison)]] ["[0]" apply ["[1]T" \\test]] [\\specification ["$[0]" monad] ["$[0]" equivalence]]] [data ["[0]" product]] [math ["[0]" random (.only Random)] [number ["n" nat]]] [test ["_" property (.only Test)]]]] [\\library ["[0]" / (.only Lazy)]]) (def injection (Injection Lazy) (|>> /.lazy)) (def comparison (Comparison Lazy) (function (_ ==) (of (/.equivalence ==) =))) (def .public lazy (All (_ a) (-> (Random a) (Random (Lazy a)))) (of random.functor each (|>> /.lazy))) (def .public test Test (with_expansions [ (is [Nat Nat] [(n.+ left right) (n.* left right)])] (<| (_.covering /._) (do random.monad [left random.nat right random.nat .let [expected ]] (_.for [/.Lazy] (all _.and (_.for [/.equivalence] ($equivalence.spec (/.equivalence n.equivalence) (..lazy random.nat))) (_.for [/.functor] (functorT.spec ..injection ..comparison /.functor)) (_.for [/.apply] (applyT.spec ..injection ..comparison /.apply)) (_.for [/.monad] ($monad.spec ..injection ..comparison /.monad)) (_.coverage [/.lazy] (let [lazy (/.lazy ) (open "_#=") (product.equivalence n.equivalence n.equivalence)] (_#= expected (/.value lazy)))) (_.coverage [/.value] (let [lazy (/.lazy )] (and (not (same? expected (/.value lazy))) (same? (/.value lazy) (/.value lazy))))) ))))))