我是Haskell的新手,并且想要生成Arbitrary树。
所以我的第一个想法是创建一个任意 bool(boolean) 值,如果为true,则返回一棵空树,否则创建一个非空树:

instance (Arbitrary a) => Arbitrary (BinaryTree a)
  arbitrary = do
    createNonEmpty <- arbitrary
    if createNonEmpty
      then return Nil
      else generateNonEmptyTree

但是这种创建 bool(boolean) 并将其仅用于该模式的模式似乎有点奇怪,并且感觉应该有一种更惯用的方式。
我可以使用的标准库中是否已经存在某种“monadic if”
arbitrary = ifM arbitrary (return Nil) (generateNonEmptyTree)

还是解决这个问题的最惯用的方法是什么?

最佳答案

特别是对于QuickCheck,我将使用oneof:

arbitrary = oneof [return Nil, generateNonEmptyTree]

它实际上完成了您在问题中提出的建议(生成一个一次性值,然后立即使用它):
oneof :: [Gen a] -> Gen a
oneof [] = error "QuickCheck.oneof used with empty list"
oneof gs = choose (0,length gs - 1) >>= (gs !!)

但是由于它是一个库函数,所以这意味着您不必在自己的代码中看到一次性的值。

10-07 20:44