4

I would like to write a SmallCheck property that uses IO, but I can't figure out how I am supposed to do it. Specifically, the goal is to write a property that is an instance of Testable IO Bool so that I can feed it into smallCheck (or testProperty in test-framework). Unfortunately, the best I can come up with is the following:

smallCheck 5 (\(x :: Int) → return True :: IO Bool)

This doesn't work because it is an instance of Testable IO (IO Bool) rather than Testable IO Bool, but I can't figure out how to rewrite it so that it works.

Any help would be appreciated.

Gregory Crosswhite
  • 1,457
  • 8
  • 17

2 Answers2

4

You want the monadic combinator. It takes an arbitrary monad m and wraps it into a Property that is an instance of Testable.

smallCheck 5  $ \(x :: Int) -> monadic $ (return True :: IO Bool)
daniel gratzer
  • 52,833
  • 11
  • 94
  • 134
2

It turns out that there is a function that does exactly what I wanted:

monadic :: Testable m a => m a -> Property m

You use it like so:

smallCheck 5 $ \(x :: Int) → monadic (putStrLn (show x) >> return True)

Specifically, note how monadic needs to be nested after the function argument.

Gregory Crosswhite
  • 1,457
  • 8
  • 17