Skip to content

Commit bfa3402

Browse files
~20% speedup
1 parent 328c0b4 commit bfa3402

File tree

1 file changed

+23
-16
lines changed

1 file changed

+23
-16
lines changed

src/Constrained/GenT.hs

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ module Constrained.GenT (
2424
suchThatT,
2525
suchThatWithTryT,
2626
scaleT,
27+
resizeT,
2728
firstGenT,
2829
tryGenT,
2930
chooseT,
@@ -34,7 +35,6 @@ module Constrained.GenT (
3435
vectorOfT,
3536
listOfUntilLenT,
3637
listOfT,
37-
resizeT,
3838
strictGen,
3939
looseGen,
4040

@@ -97,28 +97,31 @@ instance Monad GE where
9797
-- Strict gen monad
9898
------------------------------------------------------------------------
9999

100-
liftGenToStrict :: Gen a -> StrictGenT m a
100+
liftGenToStrict :: Monad m => Gen a -> StrictGenT m a
101101
liftGenToStrict g = StrictGen $ \seed size -> do
102102
let (seed', seed'') = split seed
103103
pure (seed'', unGen g seed' size)
104104

105-
runStrictGen :: StrictGenT m a -> Gen (m a)
105+
runStrictGen :: Functor m => StrictGenT m a -> Gen (m a)
106106
runStrictGen g = MkGen $ \seed size -> do
107107
snd <$> unStrictGen g seed size
108108

109-
strictGetSize :: StrictGenT m Int
109+
strictGetSize :: Applicative m => StrictGenT m Int
110110
strictGetSize = StrictGen $ \ seed size -> pure (seed, size)
111111

112+
scaleStrict :: (Int -> Int) -> StrictGenT m a -> StrictGenT m a
113+
scaleStrict f sg = StrictGen $ \ seed size -> unStrictGen sg seed (f size)
114+
112115
newtype StrictGenT m a = StrictGen { unStrictGen :: QCGen -> Int -> m (QCGen, a) }
113116

114-
instance Functor (StrictGenT m) where
117+
instance Functor m => Functor (StrictGenT m) where
115118
fmap f (StrictGen g) = StrictGen $ \ seed size -> second f <$> g seed size
116119

117-
instance Applicative (StrictGenT m) where
120+
instance Monad m => Applicative (StrictGenT m) where
118121
pure a = StrictGen $ \ seed _ -> pure (seed, a)
119122
(<*>) = ap
120123

121-
instance Monad (StrictGenT m) where
124+
instance Monad m => Monad (StrictGenT m) where
122125
StrictGen g >>= k = StrictGen $ \ seed size -> do
123126
(seed', a) <- g seed size
124127
unStrictGen (k a) seed' size
@@ -210,7 +213,7 @@ instance MonadGenError m => MonadGenError (GenT m) where
210213
fatalErrors es = GenT $ \_ xs -> lift $ fatalErrors (cat es xs)
211214

212215
-- Perhaps we want to turn fatalError into genError, if mode_ is Loose?
213-
explainNE e (GenT f) = GenT $ \mode es -> explainNE e $ f mode es
216+
explainNE e (GenT f) = GenT $ \mode es -> StrictGen $ \ seed size -> explainNE e $ unStrictGen (f mode es) seed size
214217

215218
-- ====================================================
216219
-- useful operations on NonEmpty
@@ -304,19 +307,19 @@ listFromGE = fromGE (const []) . explain "listFromGE"
304307
-- Useful operations on GenT
305308

306309
-- | Run a t`GenT` generator in `Strict` mode
307-
strictGen :: GenT m a -> Gen (m a)
310+
strictGen :: Functor m => GenT m a -> Gen (m a)
308311
strictGen genT = runStrictGen $ runGenT genT Strict []
309312

310313
-- | Run a t`GenT` generator in `Loose` mode
311-
looseGen :: GenT m a -> Gen (m a)
314+
looseGen :: Functor m => GenT m a -> Gen (m a)
312315
looseGen genT = runStrictGen $ runGenT genT Loose []
313316

314317
-- | Turn a t`GenT` generator into a `Gen` generator in `Strict` mode
315318
genFromGenT :: GenT GE a -> Gen a
316319
genFromGenT genT = errorGE <$> strictGen genT
317320

318321
-- | Turn a `Gen` generator into a t`GenT` generator that never fails.
319-
pureGen :: Applicative m => Gen a -> GenT m a
322+
pureGen :: Monad m => Gen a -> GenT m a
320323
pureGen gen = GenT $ \_ _ -> liftGenToStrict gen
321324

322325
-- | Lift `listOf` to t`GenT`
@@ -346,7 +349,7 @@ listOfUntilLenT gen goalLen validLen =
346349
-- | Lift `vectorOf` to t`GenT`
347350
vectorOfT :: MonadGenError m => Int -> GenT GE a -> GenT m [a]
348351
vectorOfT i gen = GenT $ \mode _ -> do
349-
res <- _ -- pureGen $ fmap sequence . vectorOf i $ runStrictGen $ runGenT gen Strict []
352+
res <- liftGenToStrict $ fmap sequence . vectorOf i $ runStrictGen $ runGenT gen Strict []
350353
case mode of
351354
Strict -> lift $ runGE res
352355
Loose -> case res of
@@ -381,15 +384,19 @@ suchThatWithTryT tries g p = do
381384

382385
-- | Lift `scale` to t`GenT`
383386
scaleT :: (Int -> Int) -> GenT m a -> GenT m a
384-
scaleT sc (GenT gen) = GenT $ \mode msgs -> scale sc $ gen mode msgs
387+
scaleT sc (GenT gen) = GenT $ \mode msgs -> scaleStrict sc $ gen mode msgs
388+
389+
-- | Lift `resize` to t`GenT`
390+
resizeT :: Int -> GenT m a -> GenT m a
391+
resizeT = scaleT . const
385392

386393
-- | Access the `GenMode` we are running in, useful to decide e.g. if we want
387394
-- to re-try in case of a `GenError` or give up
388-
getMode :: Applicative m => GenT m GenMode
395+
getMode :: Monad m => GenT m GenMode
389396
getMode = GenT $ \mode _ -> pure mode
390397

391398
-- | Get the current stack of `explain` above you
392-
getMessages :: Applicative m => GenT m [NonEmpty String]
399+
getMessages :: Monad m => GenT m [NonEmpty String]
393400
getMessages = GenT $ \_ msgs -> pure msgs
394401

395402
-- | Locally change the generation mode
@@ -418,7 +425,7 @@ chooseT (a, b)
418425

419426
-- | Get the size provided to the generator
420427
sizeT :: Monad m => GenT m Int
421-
sizeT = GenT $ \mode msgs -> strictGetSize
428+
sizeT = GenT $ \_ _ -> strictGetSize
422429

423430
-- ==================================================================
424431
-- Reflective analysis of the internal GE structure of (GenT GE x)

0 commit comments

Comments
 (0)