Как вы переопределяете экземпляры классов типа Haskell, предоставляемые кодом пакета? - PullRequest
11 голосов
/ 13 апреля 2011

У меня есть старый код на 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))]

Приведенный выше код вызывает ошибку объявления повторяющегося экземпляра во время компиляции.Я могу вынуть этот код и обойтись с генератором по умолчанию, но я хотел бы знать, как правильно решить эту проблему.

Одно из возможных решений, которое я рассматривал (но не тестировал), - это псевдоним Word8используя newtype.Это повлечет за собой множество изменений во всем источнике, поэтому я надеюсь, что есть более чистый способ.

РЕДАКТИРОВАТЬ: Как упоминалось в комментариях ниже, принятый ответ был очень чистым и простым в реализации:

newtype EncodedByte = EncodedByte Word8

instance Arbitrary EncodedByte where
  arbitrary = liftM EncodedByte $ frequency [(2, elements [ctrlFrameDelim, ctrlEscape, ctrlXon, ctrlXoff]),
                                             (8, choose (0, 255))]

1 Ответ

10 голосов
/ 13 апреля 2011
Псевдоним

A 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(..)
...