Search code examples
haskellquickcheck

context-sensitive generation using quick check


I would like to generate random terms based on some sort of "context" and I was wondering if this is possible using quickcheck. Basically I would like to have an additional data type passed around so that the arbitrary function can generate terms based on the additional parameter... Is this possible with quickcheck or should I just write my own definition of Gen?


Solution

  • It's possible, though not really sane, to do this from within arbitrary. But if you step out of arbitrary, you can literally just pass an extra parameter around.

    -- do whatever you want inside the implementation of these two
    chooseIntRange :: Context -> Int
    updateContext :: Int -> Context -> Context
    
    arbitraryIntWithContext :: Context -> Gen (Context, Int)
    arbitraryIntWithContext ctx = do
        n <- choose (0, chooseIntRange ctx)
        return (n, updateContext n ctx)
    

    The plumbing of the context can be relieved somewhat with StateT, e.g.

    -- do whatever you want inside the implementation of this
    chooseIntRangeAndUpdate :: MonadState Context m => m Int
    
    arbitraryIntStateT :: StateT Context Gen Int
    arbitraryIntStateT = do
        hi <- chooseIntRangeAndUpdate
        lift (choose (0, hi))