为使用Maybe的newtype创建任意实例

Mar*_* L. 3 haskell quickcheck

我想Arbitrary为以下newtype 创建一个实例,以便将其用于QuickCheck:

newtype Wrapmaybe a = Wrapmaybe {getMaybe :: Maybe a} deriving (Eq, Show)
Run Code Online (Sandbox Code Playgroud)

我知道Arbitrary实例Maybe可以写成如下:

instance Arbitrary a => Arbitrary (Maybe a) where
     arbitrary = frequency [(1, return Nothing), (1, liftM Just arbitrary)]
Run Code Online (Sandbox Code Playgroud)

如何Arbitrary在不出现类型错误或类型错误的情况下为以下内容编写实例:

instance Arbitrary a => Arbitrary (Wrapmaybe Maybe a) where
   etc...
Run Code Online (Sandbox Code Playgroud)

lef*_*out 10

好吧,你可以Maybe用你newtype的相应构造函数替换该实例中的每个构造函数:

instance Arbitrary a => Arbitrary (WrapMaybe a) where
  arbitrary = frequency [ (1, return $ WrapMaybe Nothing)
                        , (1, fmap (WrapMaybe . Just) arbitrary) ]
Run Code Online (Sandbox Code Playgroud)

但是,使用现有Maybe实例对结果执行此操作一次更简单:

instance Arbitrary a => Arbitrary (WrapMaybe a) where
  arbitrary = fmap WrapMaybe arbitrary
Run Code Online (Sandbox Code Playgroud)

你也可以写WrapMaybe <$> arbitrary.但是请不要使用liftM,这是过时的!(这些都是等价的.)

  • ...或者打开`GeneralizedNewtypeDeriving`并将`Arbitrary`添加到派生实例列表中. (8认同)