型クラスはArbitrary
インスタンスが定義されている存在量化辞書に具体化され
{-# LANGUAGE GADTs, ScopedTypeVariables #-}
import Test.QuickCheck hiding (Gen)
class Gen a where
next :: a -> a
prev :: a -> a
np_prop :: SomeGen -> Bool
np_prop (SomeGen a) = prev (next a) == a
main :: IO()
main = quickCheck np_prop
instance Gen Bool where
next True = False
next False = True
prev True = False
prev False = True
instance Gen Int where
next = (+ 1)
prev = subtract 1
data SomeGen where
SomeGen :: (Show a, Eq a, Arbitrary a, Gen a) => a -> SomeGen
instance Show SomeGen where
showsPrec p (SomeGen a) = showsPrec p a
show (SomeGen a) = show a
instance Arbitrary SomeGen where
arbitrary = do
GenDict (Proxy :: Proxy a) <- arbitrary
a :: a <- arbitrary
return $ SomeGen a
shrink (SomeGen a) =
map SomeGen $ shrink a
data GenDict where
GenDict :: (Show a, Eq a, Arbitrary a, Gen a) => Proxy a -> GenDict
instance Arbitrary GenDict where
arbitrary =
elements
[ GenDict (Proxy :: Proxy Bool)
, GenDict (Proxy :: Proxy Int)
]
data Proxy a = Proxy
してみてください。このArbitrary
ディクショナリインスタンスを使用して、現存する定量化された値に対してArbitrary
のインスタンスを定義します。
もう1つの例はhttps://github.com/sonyandy/var/blob/4e0b12c390eb503616d53281b0fd66c0e1d0594d/tests/properties.hs#L217です。
ConstraintKinds
を使用する場合は、これをさらに一般化することができます(また、定型文を減らすこともできます)。以下は一度だけ定義されています。テストしたい各タイプのクラスについては
data Some c where
Some :: (Show a, Arbitrary a, c a) => a -> Some c
instance Show (Some c) where
showsPrec p (Some a) = showsPrec p a
show (Some a) = show a
instance Arbitrary (Dict c) => Arbitrary (Some c) where
arbitrary = do
Dict (Proxy :: Proxy a) :: Dict c <- arbitrary
a :: a <- arbitrary
return $ Some a
shrink (Some a) =
map Some $ shrink a
data Dict c where
Dict :: (Show a, Arbitrary a, c a) => Proxy a -> Dict c
data Proxy a = Proxy
class (c a, d a) => (c &&# d) a
instance (c a, d a) => (c &&# d) a
、Dict
のArbitrary
インスタンスが必要です。輸入
instance Arbitrary (Dict (Eq &&# Gen)) where
arbitrary =
elements
[ Dict (Proxy :: Proxy Bool)
, Dict (Proxy :: Proxy Int)
]
np_prop :: Some (Eq &&# Gen) -> Bool
np_prop (Some a) = prev (next a) == a
パラレル 'のsrc /'と 'テスト/'ディレクトリを使用するには、 'HS-ソース-dirsにを設定することをお勧めします:SRC、あなたの' .cabal'ファイルでtest'ているので、両方のディレクトリモジュール検索パスにあります。 – hammar
内部にプロパティが存在しないのはなぜですか? – alternative
彼らは確かにテストを受けるのが難しく、(私の経験では)実装の詳細の代わりにエクスポートされた動作をテストするほうがずっと便利です。 – So8res