You want to use a stateT esque monad that does a split within the bind. Quickcheck should have an example of this. 

On Fri, Jul 17, 2020 at 2:47 AM Dannyu NDos <ndospark320@gmail.com> wrote:
Though it is reasonable to make utilities monadic, they lack a crucial property: laziness.

I have the following datatype:

newtype ArbReal = ArbReal (Word -> Integer)

This represents arbitrary real numbers by being able to compute arbitrary decimal places after the decimal point. For example, to compute pi, let f be the function passed to constructor ArbReal. Then f 0 = 3, f 1 = 31, f 2 = 314, and so on.

I can implement instance Random ArbReal:

instance Random ArbReal where
    random g = let
        (h, i) = split g
        d:digits = randomRs (0 :: Word, 9) h
        getNum [] = 0
        getNum (d:ds) = toInteger d + 10 * getNum ds
        takeDigits n = getNum (reverse (take n digits)) + toInteger (fromEnum (d >= 5))
        in (ArbReal (takeDigits . fromIntegral), i)
    randomR (lo, hi) g = let
        (x, h) = random g
        in (lo + x * (hi - lo), h)

But I see no way to implement an instance of UniformRange ArbReal, for it relies on randomRs, which is lazy. Neither ST nor IO is able to contain such laziness.
_______________________________________________
Libraries mailing list
Libraries@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries