简体   繁体   English

Monadic if else

[英]Monadic if else

I am new to Haskell and want to generate an Arbitrary tree. 我是Haskell的新手,想要生成一个Arbitrary树。
So my first idea is to create an arbitary bool, if it is true then return an empty tree and else create a non-empty one: 所以我的第一个想法是创建一个仲裁bool,如果它是真的然后返回一个空树,否则创建一个非空的树:

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

But this pattern of creating the bool and use it just for that if seems a bit odd and it feels like there should be a more idiomatic way. 但是这种创造bool的模式并且仅仅为了它而使用它似乎有点奇怪,并且感觉应该有更惯用的方式。
Is there already some kind of "monadic if" in the standard library that I could use like 在我可以使用的标准库中是否已经存在某种“monadic if”

arbitrary = ifM arbitrary (return Nil) (generateNonEmptyTree)

Or what else is the most idiomatic way to solve this? 或者还有哪种方法可以解决这个问题呢?

For QuickCheck in particular, I'd use oneof : 对于快速检查特别,我会使用oneof

arbitrary = oneof [return Nil, generateNonEmptyTree]

It does essentially what you propose in your question (generate a one-off value, then use it immediately): 它基本上是你在你的问题中提出的建议(生成一次性值,然后立即使用它):

oneof :: [Gen a] -> Gen a
oneof [] = error "QuickCheck.oneof used with empty list"
oneof gs = choose (0,length gs - 1) >>= (gs !!)

But since it's a library function, this means you don't have to see the one-off values in your own code. 但由于它是库函数,这意味着您不必在自己的代码中看到一次性值。

My general solution to the "use once binding" is -XLambdaCase : 我对“使用一次绑定”的一般解决方案是-XLambdaCase

instance (Arbitrary a) => Arbitrary (BinaryTree a)
  arbitrary = arbitrary >>= \case
    True  -> return Nil
    False -> generateNonEmptyTree

Alternately, you could use something like 或者,您可以使用类似的东西

bool :: a -> a -> Bool -> a
bool f _ False = f
bool _ t True = t

( Bool 's equivalent to either or foldr ) 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