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