如何覆盖程序包代码提供的Haskell类型类实例?

| 我有一些旧的Haskell代码,其中包括QuickCheck测试用例。较新版本的QuickCheck(我刚刚升级到2.4.0.1)包括用于
Arbitrary Word8
和其他类型的类实例。在较旧的Test.QuickCheck.Arbitrary 2.0.x版本中不存在这些功能。 虽然从广义上讲很有用,但软件包提供的
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))]
    
已邀请:
newtype
别名是此处的标准解决方案。在大多数情况下(可能不包括您的情况),这没什么大不了的,因为新类型包装器仅需要出现在使用任意类型类的位置。例如,您可能具有一些顶级:
x <- arbitrary
相反,您将拥有
newtype SomeNewType = SNT Word8
instance Arbitrary SomeNewType where ...
....
    SNT x <- arbitrary
您可能想要的不是作为GHC扩展存在的-您想要显式导入和导出实例。如果您有明确的实例导入,则将允许:
import Test.QuickCheck hiding (Arbitrary(Word8))
但是通过隐式导入实例来破坏当前有效的许多代码:
import Test.QuickCheck (quickCheck) -- note the implicit import of Arbitrary(..)
    

要回复问题请先登录注册