我是Haskell的新手,想要生成一Arbitrary棵树.
所以我的第一个想法是创建一个仲裁bool,如果它是真的然后返回一个空树,否则创建一个非空的树:
instance (Arbitrary a) => Arbitrary (BinaryTree a)
arbitrary = do
createNonEmpty <- arbitrary
if createNonEmpty
then return Nil
else generateNonEmptyTree
Run Code Online (Sandbox Code Playgroud)
但是这种创造bool的模式并且仅仅为了它而使用它似乎有点奇怪,并且感觉应该有更惯用的方式.
在我可以使用的标准库中是否已经存在某种"monadic if"
arbitrary = ifM arbitrary (return Nil) (generateNonEmptyTree)
Run Code Online (Sandbox Code Playgroud)
或者还有哪种方法可以解决这个问题呢?
特别是对于QuickCheck,我会使用oneof:
arbitrary = oneof [return Nil, generateNonEmptyTree]
Run Code Online (Sandbox Code Playgroud)
它基本上是你在你的问题中提出的建议(生成一次性值,然后立即使用它):
oneof :: [Gen a] -> Gen a
oneof [] = error "QuickCheck.oneof used with empty list"
oneof gs = choose (0,length gs - 1) >>= (gs !!)
Run Code Online (Sandbox Code Playgroud)
但由于它是库函数,这意味着您不必在自己的代码中看到一次性值.
我对"使用一次绑定"的一般解决方案是-XLambdaCase:
instance (Arbitrary a) => Arbitrary (BinaryTree a)
arbitrary = arbitrary >>= \case
True -> return Nil
False -> generateNonEmptyTree
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用类似的东西
bool :: a -> a -> Bool -> a
bool f _ False = f
bool _ t True = t
Run Code Online (Sandbox Code Playgroud)
(Bool相当于either或foldr)
instance (Arbitrary a) => Arbitrary (BinaryTree a)
arbitrary = bool generateNonEmptyTree (return Nil) =<< arbitrary
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
173 次 |
| 最近记录: |