Is there a monadic version of Arbitrary to use with QuickCheck?
Asked Answered
J

2

9

When I want to test pure code using QuickCheck I often have to write an Arbitrary instance. To test monadic code, I can use Test.QuickCheck.Monadic as described in this article.

My question is: Is there some canonical way to generate data that depends on a monadic context? In particular, is there some monadic version of Arbitrary? How would you go about generating data that requires a monadic context?

Jackfruit answered 25/3, 2012 at 19:53 Comment(0)
Q
3

Randomly generate a context

Just generate an appropriate random monadic context. If you are running tests, you can't stay in pure imaginary monad land, you actually have to pick a particular monad to test out. Did you pick a list monad? Randomly generate a list as the context. A state monad? Randomly generate a value of the state type for the context. Writer? Randomly generate a log.

Randomly generate an action

So what do you want to generate, exactly? If it is a monadic action, then you need to provide a way of generating monadic actions for your particular monad, based on its unique primitives. e.g. randomly generated State actions should be constructed randomly from State primitives get and put.

Put them together

If you use QuickCheck's capabilities to generate a function fthat produces a monadic action, and use QuickCheck to generate a context c, then you can simply c >>= f to put them together. Or you can simply generate the action a directly, and do c >> a.

Quiet answered 26/3, 2012 at 3:38 Comment(0)
S
6

Gen is basically what you use to work with Arbitrary instances in a monad framework, since the Arbitrary type class is basically just a provider of Gen a generators.

Swelling answered 26/3, 2012 at 0:42 Comment(0)
Q
3

Randomly generate a context

Just generate an appropriate random monadic context. If you are running tests, you can't stay in pure imaginary monad land, you actually have to pick a particular monad to test out. Did you pick a list monad? Randomly generate a list as the context. A state monad? Randomly generate a value of the state type for the context. Writer? Randomly generate a log.

Randomly generate an action

So what do you want to generate, exactly? If it is a monadic action, then you need to provide a way of generating monadic actions for your particular monad, based on its unique primitives. e.g. randomly generated State actions should be constructed randomly from State primitives get and put.

Put them together

If you use QuickCheck's capabilities to generate a function fthat produces a monadic action, and use QuickCheck to generate a context c, then you can simply c >>= f to put them together. Or you can simply generate the action a directly, and do c >> a.

Quiet answered 26/3, 2012 at 3:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.