[英]QuickCheck Haskell - generating random lottery tickets
這有效:
genAnimal :: Gen String
genAnimal = do
animals <- shuffle ["tiger","rabbit","dragon","snake","rat","ox","pig","sheep","horse","monkey","dog"]
return (head animals)
genWinner :: Gen String
genWinner = do
animal <- genAnimal
prize <- choose (10::Int,1000::Int)
return (unwords (replicate 3 animal) ++ " " ++ show prize)
genTicket :: Gen String
genTicket = do
animals <- replicateM 3 genAnimal
prize <- choose (10::Int,1000::Int)
return (unwords animals ++ " " ++ show prize)
genTickets :: Gen [String]
genTickets = do
tickets <- replicateM 6 (oneof [genWinner, genTicket])
return tickets
但是看起來很笨拙,是否有更明智的方式組合這些發電機? 它基本上會選擇三只隨機動物,然后隨機抽取獎品,然后制作六張門票。
正如@AJFarmar指出的那樣,您可以使用elements
組合器從列表中選擇一個隨機元素,而不用改編版本的標題:
genAnimal :: Gen String
genAnimal = elements ["tiger","rabbit","dragon","snake","rat","ox",
"pig","sheep","horse","monkey","dog"]
此外,應用樣式通常可以更簡潔,特別是如果您為結合了結果的純計算引入輔助函數時:
genPrize :: Gen Int
genPrize = choose (10,1000)
genTicket :: Gen String
genTicket = ticket <$> replicateM 3 genAnimal <*> genPrize
where ticket animals prize = unwords animals ++ " " ++ show prize
其他一些其他改進可能來自:
unword
並用空格粘在一起的字符串; String
形式打印它; gen
前綴 vectorOf
別名replicateM
這是在這種情況下稍微更具有可讀性。 這可能會導致類似:
{-# OPTIONS_GHC -Wall #-}
module Lottery where
import Test.QuickCheck
type Animal = String
data Ticket = Ticket [Animal] Int
pticket :: Ticket -> String
pticket (Ticket ts prz) = unwords ts ++ ' ':show prz
tickets :: Gen [Ticket]
tickets = vectorOf 6 (oneof [winner, loser])
where winner = Ticket <$> (replicate 3 <$> animal) <*> prize
loser = Ticket <$> (vectorOf 3 animal) <*> prize
animal = elements ["tiger","rabbit","dragon","snake","rat","ox",
"pig","sheep","horse","monkey","dog"]
prize = choose (10,1000)
main :: IO ()
main = print . map pticket =<< generate tickets
我認為看起來不錯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.