اختبار خصائص QuickCheck ضد أنواع متعددة؟
-
11-09-2019 - |
سؤال
لدي فئة من النوع Atomic
, ، الذي يحدد الوظائف لتحويل أنواع معينة إلى / من قيمة التفاف (Atom
). أود تحديد خاصية QuickCheck التي تنص على: "لجميع مثيلات Atomic
, ، قد يتم تخزين أي قيمة واسترجاعها بأمان ". يبدو أن العقار مثل هذا:
class Atomic a where
toAtom :: a -> Atom
fromAtom :: Atom -> Maybe a
prop_AtomIdentity x = fromAtom (toAtom x) == Just x
ومع ذلك، إذا حاولت فقط تشغيل هذه الخاصية من خلال QuickCheck، فهذا فقط يختار مثيل واحد (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
لكنه فشل مع خطأ Typecheck:
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)]
هل هناك طريقة أفضل لاختبار خاصية مراقبة الجودة ضد أنواع متعددة؟ إذا لم يكن الأمر كذلك، فسيتم إجراء ForAllatoms للعمل أو أنه غير مدعوم من نظام النوع؟
المحلول
لا أستطيع تجميع التعليمات البرمجية الخاصة بك، لذلك ... طلقة عمياء:
يحاول
forallAtoms :: (forall a. (Atomic a, Show a) => a -> Bool) -> [TestOptions -> IO TestResult]
كوقعات نوع. هذا يحتاج إلى امتداد لغة -xrankntypes.
المشكلة التي لديك، كما أراها، هي أن GHC يحاول العثور عليها واحد اكتب لإدراج ل a
في x :: (a -> Bool)
لنطاق الوظيفة بأكمله، لكنك تعطي بالفعل ثلاثة مختلفة هناك.