[英]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.