生成一个保证有7个列表的列表

Sal*_*ati 2 haskell list quickcheck

我该怎么做呢?我想要一些sevenList :: Gen [Integer]产生列表的结构,并且保证总是包含至少一个7.

我知道如果我想生成一个大小为n的列表,我可以这样做:

listOfLength n gen = sequence [ gen | i <- [1..n] ]
Run Code Online (Sandbox Code Playgroud)

但这还不够,因为如果我生成一个长度为10的列表并且没有生成7,我必须继续,但此刻它不会.

Wil*_*sem 6

您可以决定生成两个列表,然后构建一个列表,我们将列表夹在它们之间.

例如:

genSevenList :: Gen [Integer]
genSevenList = do
    la <- arbitrary
    lb <- arbitrary
    return $ la ++ 7 : lb
Run Code Online (Sandbox Code Playgroud)

因此,前两个语句生成两个任意[Integer]列表,然后我们return $ la ++ 7 : lb.因此,我们预先准备lb7,并追加这la.

您还可以生成一个任意列表,将其拆分为随机索引,然后将这些部分连接在一起,如上所述.例如:

genSevenList :: Gen [Integer]
genSevenList = do
    l <- arbitrary
    k <- choose (0,length l)
    let (la,lb) = splitAt k l
    return $ la ++ 7 : lb
Run Code Online (Sandbox Code Playgroud)

虽然两者都能够生成所有可能的列表,比如@leftroundabout说,但是第二个实现更有可能出现更短的列表,因为两个aribtrary调用生成短列表(或空列表)的几率不是那个大.

  • 两种方法之间的主要区别在于,使用两个单独的"任意"列表,两者都不可能是空的,即"[7]"的情况可能不会经常发生.因此,生成一个列表并在某处注入七个可能更适合于覆盖测试. (2认同)