繁体   English   中英

Monadic if else

[英]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的相当于eitherfoldr

instance (Arbitrary a) => Arbitrary (BinaryTree a)
  arbitrary = bool generateNonEmptyTree (return Nil) =<< arbitrary

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM