[英]Monadic if else
我是Haskell的新手,想要生成一个Arbitrary
树。
所以我的第一个想法是创建一个仲裁bool,如果它是真的然后返回一个空树,否则创建一个非空的树:
instance (Arbitrary a) => Arbitrary (BinaryTree a)
arbitrary = do
createNonEmpty <- arbitrary
if createNonEmpty
then return Nil
else generateNonEmptyTree
但是这种创造bool的模式并且仅仅为了它而使用它似乎有点奇怪,并且感觉应该有更惯用的方式。
在我可以使用的标准库中是否已经存在某种“monadic if”
arbitrary = ifM arbitrary (return Nil) (generateNonEmptyTree)
或者还有哪种方法可以解决这个问题呢?
对于快速检查特别,我会使用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 !!)
但由于它是库函数,这意味着您不必在自己的代码中看到一次性值。
我对“使用一次绑定”的一般解决方案是-XLambdaCase
:
instance (Arbitrary a) => Arbitrary (BinaryTree a)
arbitrary = arbitrary >>= \case
True -> return Nil
False -> generateNonEmptyTree
或者,您可以使用类似的东西
bool :: a -> a -> Bool -> a
bool f _ False = f
bool _ t True = t
( Bool
的相当于either
或foldr
)
instance (Arbitrary a) => Arbitrary (BinaryTree a)
arbitrary = bool generateNonEmptyTree (return Nil) =<< arbitrary
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.