Atomic
特定の型をラッパー値()との間で変換するための関数を定義する型クラスがありますAtom
。Atomic
「のすべてのインスタンスについて、任意の値を安全に保存および取得できます」というQuickCheckプロパティを定義したいと思います。プロパティは次のようになります。
class Atomic a where
toAtom :: a -> Atom
fromAtom :: Atom -> Maybe a
prop_AtomIdentity x = fromAtom (toAtom x) == Just x
ただし、QuickCheckを介してそのプロパティを実行しようとすると、1つのインスタンス(Bool
)を選択してテストするだけです。私は現在、テストリストでサポートされている各アトミック型の型シグネチャを定義することでこれを回避していますが、これは冗長でエラーが発生しやすいです。
containerTests =
[ run (prop_AtomIdentity :: Bool -> Bool)
, run (prop_AtomIdentity :: Word8 -> Bool)
, run (prop_AtomIdentity :: String -> Bool)
{- etc -} ]
これを自動的に行う関数を定義しようとしています:
forallAtoms :: (Atomic a, Show a) => (a -> Bool) -> [TestOptions -> IO TestResult]
forallAtoms x =
[ run (x :: Bool -> Bool)
, run (x :: Word8 -> Bool)
, run (x :: String -> Bool)
{- etc -} ]
containerTests = forallAtoms prop_AtomIdentity
ただし、タイプチェックエラーで失敗します。
Tests/Containers.hs:33:0:
Couldn't match expected type `Word8' against inferred type `String'
In the first argument of `run', namely `(x :: Word8 -> Bool)'
In the expression: run (x :: Word8 -> Bool)
In the expression:
[run (x :: Bool -> Bool), run (x :: Word8 -> Bool),
run (x :: String -> Bool)]
複数のタイプに対してQCプロパティをテストするためのより良い方法はありますか?そうでない場合、forallAtomsを機能させることができますか、それとも型システムでサポートされていませんか?