I have a custom result/error monad, nothing fancy:
import Control.Monad (liftM, ap)
data MyResult a = Error String | Success a
instance Functor MyResult where
fmap = liftM
instance Applicative MyResult where
pure = return
(<*>) = ap
instance Monad MyResult where
(Error s) >>= f = Error s
(Success a) >>= f = f a
return = Success
I want values in this monad to instantiate QuickCheck's Testable class, so I can write properties that hold (i.e. pass tests) when a value is Success _, and not hold (i.e. fail tests) when a value is Error _.
For example, I would like to be able to write a test like this:
myProp :: Property
myProp = forAll (arbitrary :: Int)
(\x -> if x == 0 then Error "0 not allowed" else Success ())
and have the String in the Error be the test failure message if the test fails.
I assume I need to instantiate Testable for MyResult:
instance Testable t => Testable (MyResult t) where
property (Success _) = undefined -- what goes here?
property (Error s) = undefined -- what goes here?
However I can't figure out how I should implement the property function in Testable, despite reading the QuickCheck documentation and relevant source code.
Any help here is greatly appreciated.
Aucun commentaire:
Enregistrer un commentaire