如何为递归数据类型创建任意实例?

The*_*Cat 5 haskell

我认为这会创建长度为3的任意列表,但是如何创建任意长度的列表?

import Test.QuickCheck

data List a =
  Nil
  | Cons a (List a)
  deriving (Eq, Show)

instance Arbitrary a  => Arbitrary (List a) where
  arbitrary = do
    a <- arbitrary
    a' <- arbitrary
    a'' <- arbitrary
    return $ (Cons a (Cons a' (Cons a'' (Nil))))
Run Code Online (Sandbox Code Playgroud)

Zet*_*eta 7

随着sized.它使您能够管理生成的大小arbitrary,尽管语义取决于实例:

instance Arbitrary a => Arbitrary (List a)  where
  arbitrary = sized go
    where go 0 = pure Nil
          go n = do
            xs <- go (n - 1)
            x  <- arbitrary
            return (Cons x xs)
Run Code Online (Sandbox Code Playgroud)

为了便于比较,这里[]任意实例:

instance Arbitrary a => Arbitrary [a] where
  arbitrary = sized $ \n ->
    do k <- choose (0,n)
       sequence [ arbitrary | _ <- [1..k] ]
Run Code Online (Sandbox Code Playgroud)