我有一些包含QuickCheck測試用例的舊Haskell代碼。較新版本的QuickCheck(我剛剛升級到2.4.0.1)包含Arbitrary Word8
等的類型實例。這些在Test.QuickCheck.Arbitrary較早的2.0.x版本中不存在。如何覆蓋程序包代碼提供的Haskell類型類實例?
雖然有用在一般意義上,包提供的Arbitrary Word8
發生器是不是我想用我的測試套件:
instance Arbitrary Word8 where
arbitrary = frequency [(2, oneof [return ctrlFrameDelim, return ctrlEscape, return ctrlXon, return ctrlXoff]),
(8, choose (0, 255))]
上面的代碼導致重複實例聲明的錯誤在編譯時。我可以把這段代碼拿出來,並通過默認的發生器獲取,但我想知道解決這個問題的正確方法。
我考慮過的一個可能的解決方案是使用newtype
來別名Word8
。這將導致整個源代碼的很多變化,所以我希望有一個更清晰的方法。
編輯:由於在下面的評論中提到,接受的答案很乾淨,容易實現:
newtype EncodedByte = EncodedByte Word8
instance Arbitrary EncodedByte where
arbitrary = liftM EncodedByte $ frequency [(2, elements [ctrlFrameDelim, ctrlEscape, ctrlXon, ctrlXoff]),
(8, choose (0, 255))]
很多人似乎認爲這個解決方案難看。但是如果你允許「數據類型」的含義超過價值的表示,我覺得這是完全合理的。例如,你不只是在談論'Word8',你正在談論'ControlCode'或類似的東西。 – luqui 2011-04-13 01:42:09
工作很好。事實證明,別名不需要任何級聯更改。我只需要爲「選擇」提供一個額外的「實例Random SomeNewType」聲明。 – 2011-04-13 03:23:36