@@ -6,17 +6,36 @@ module Test.QuickCheck.LCG
66 Size (),
77 LCG (),
88 repeatable ,
9- sized ,
109 stateful ,
10+ variant ,
11+ sized ,
1112 resize ,
13+ choose ,
14+ chooseInt ,
15+ oneOf ,
16+ frequency ,
17+ listOf ,
18+ listOf1 ,
19+ vectorOf ,
20+ elements ,
1221 runGen ,
1322 evalGen ,
1423 perturbGen ,
15- uniform
24+ uniform ,
25+ showSample ,
26+ showSample'
1627 ) where
1728
1829import Control.Monad.Eff
1930import Control.Monad.Eff.Random
31+ import Debug.Trace
32+ import Data.Maybe
33+ import Data.Tuple
34+ import Data.Foldable
35+ import Data.Traversable
36+ import Data.Monoid.Sum
37+ import qualified Data.Array as A
38+ import qualified Math as M
2039
2140type LCG = Number
2241type Size = Number
@@ -30,20 +49,76 @@ data Gen a = Gen (GenState -> GenOut a)
3049repeatable :: forall a b . (a -> Gen b ) -> Gen (a -> b )
3150repeatable f = Gen $ \s -> { value: \a -> (runGen (f a) s).value, state: s }
3251
33- sized :: forall a . (Number -> Gen a ) -> Gen a
34- sized f = stateful (\s -> f s.size)
35-
3652stateful :: forall a . (GenState -> Gen a ) -> Gen a
3753stateful f = Gen (\s -> runGen (f s) s)
3854
39- resize :: forall a . Number -> Gen a -> Gen a
40- resize sz g = Gen (\s -> runGen g s { size = sz })
55+ variant :: forall a . LCG -> Gen a -> Gen a
56+ variant n g = Gen $ \s -> runGen g s { newSeed = n }
57+
58+ sized :: forall a . (Size -> Gen a ) -> Gen a
59+ sized f = stateful (\s -> f s.size)
60+
61+ resize :: forall a . Size -> Gen a -> Gen a
62+ resize sz g = Gen $ \s -> runGen g s { size = sz }
63+
64+ choose :: Number -> Number -> Gen Number
65+ choose a b = (*) (max - min) >>> (+) min <$> uniform where
66+ min = M .min a b
67+ max = M .max a b
68+
69+ chooseInt :: Number -> Number -> Gen Number
70+ chooseInt a b = M .floor <$> choose (M .ceil a) (M .floor b + 0.999999999 )
71+
72+ oneOf :: forall a . Gen a -> [Gen a ] -> Gen a
73+ oneOf x xs = do
74+ n <- chooseInt 0 (A .length xs)
75+ if n == 0 then x else fromMaybe x (xs A .!! (n - 1 ))
76+
77+ frequency :: forall a . Tuple Number (Gen a ) -> [Tuple Number (Gen a )] -> Gen a
78+ frequency x xs = let
79+ xxs = x : xs
80+ total = runSum $ fold (((Sum <<< fst) <$> xxs) :: [Sum ])
81+ pick n d [] = d
82+ pick n d ((Tuple k x) : xs) = if n <= k then x else pick (n - k) d xs
83+ in do
84+ n <- chooseInt 1 total
85+ pick n (snd x) xxs
86+
87+ listOf :: forall a . Gen a -> Gen [a ]
88+ listOf g = sized $ \n ->
89+ do k <- chooseInt 0 n
90+ vectorOf k g
91+
92+ listOf1 :: forall a . Gen a -> Gen (Tuple a [a ])
93+ listOf1 g = sized $ \n ->
94+ do k <- chooseInt 0 n
95+ x <- g
96+ xs <- vectorOf (k - 1 ) g
97+ return $ Tuple x xs
98+
99+ vectorOf :: forall a . Number -> Gen a -> Gen [a ]
100+ vectorOf k g = sequence $ const g <$> (A .range 1 k)
101+
102+ elements :: forall a . a -> [a ] -> Gen a
103+ elements x xs = do
104+ n <- chooseInt 0 (A .length xs)
105+ pure if n == 0 then x else fromMaybe x (xs A .!! (n - 1 ))
41106
42107runGen :: forall a . Gen a -> GenState -> GenOut a
43108runGen (Gen f) = f
44109
45110evalGen :: forall a . Gen a -> GenState -> a
46111evalGen gen st = (runGen gen st).value
112+
113+ sample :: forall r a . Size -> Gen a -> [a ]
114+ sample sz g = evalGen (vectorOf sz g) { newSeed: 0 , size: sz }
115+
116+ showSample' :: forall r a . (Show a ) => Size -> Gen a -> Eff (trace :: Trace | r ) Unit
117+ showSample' n g = print $ sample n g
118+
119+ showSample :: forall r a . (Show a ) => Gen a -> Eff (trace :: Trace | r ) Unit
120+ showSample = showSample' 10
121+
47122--
48123-- Magic Numbers
49124--
@@ -96,5 +171,4 @@ instance bindGen :: Bind Gen where
96171 (>>=) (Gen f) g = Gen $ \s -> case f s of
97172 { value = value, state = state } -> runGen (g value) state
98173
99- instance monadGen :: Monad Gen
100-
174+ instance monadGen :: Monad Gen
0 commit comments