簡體   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