12

Atomic特定の型をラッパー値()との間で変換するための関数を定義する型クラスがありますAtomAtomic「のすべてのインスタンスについて、任意の値を安全に保存および取得できます」という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を機能させることができますか、それとも型システムでサポートされていませんか?

4

1 に答える 1

12

私はあなたのコードをコンパイルできないので...ブラインドショット:

試す

forallAtoms :: (forall a. (Atomic a, Show a) => a -> Bool) -> [TestOptions -> IO TestResult]

型署名として。これには、-XRankNTypes言語拡張が必要です。

私が見ているように、あなたが抱えている問題は、GHCが関数スコープ全体に対して挿入する1つのタイプを見つけよとすることですが、すでに3つの異なるタイプを指定しています。ax :: (a -> Bool)

于 2009-09-19T18:40:33.913 に答える