@@ -97,6 +97,26 @@ instance Monad GE where
9797-- Threading gen monad
9898------------------------------------------------------------------------
9999
100+ -- The normal Gen monad always splits the seed when doing >>=. This is for very
101+ -- good reasons - it lets you write generators that generate infinite data to
102+ -- the left of a >>= and let's your generators be very lazy!
103+
104+ -- A traditional GenT m a implementation would inherit this splitting behaviour
105+ -- in order to let you keep writing infinite and lazy things to the left of >>=
106+ -- on the GenT m level. Now, the thing to realize about this is that unless
107+ -- your code is very carefully written to avoid it this means you're going to
108+ -- end up with unnecessary >>=s and thus unnecessary splits.
109+
110+ -- To get around this issue of unnecessary splits we introduce a threading GenT
111+ -- implementation here that sacrifices letting you do infinite (and to some
112+ -- extent lazy) structures to the left of >>= on the GenT m level, but doesn't
113+ -- prohibit you from doing so on the Gen level.
114+
115+ -- This drastically reduces the number of seed splits while still letting you
116+ -- write lazy and infinite generators in Gen land by being a little bit more
117+ -- careful. It works great for constrained-generators in particular, which has
118+ -- a tendency to be strict and by design avoids inifinte values.
119+
100120liftGenToThreading :: Monad m => Gen a -> ThreadingGenT m a
101121liftGenToThreading g = ThreadingGen $ \ seed size -> do
102122 let (seed', seed'') = split seed
0 commit comments