Class Haskell:使用monad类
作为一项任务,我需要与哈斯凯尔的蒙纳德合作,创建一个赌博游戏,它有一个简单的规则:掷6枚硬币,数人头,掷骰子,如果结果等于或大于你赢的人头数,否则你输。我得到了以下定义赌博单子的“框架”:Class Haskell:使用monad类,class,haskell,monads,Class,Haskell,Monads,作为一项任务,我需要与哈斯凯尔的蒙纳德合作,创建一个赌博游戏,它有一个简单的规则:掷6枚硬币,数人头,掷骰子,如果结果等于或大于你赢的人头数,否则你输。我得到了以下定义赌博单子的“框架”: data Coin = H | T deriving (Bounded, Eq, Enum, Ord, Show) data Dice = D1 | D2 | D3 | D4 | D5 | D6 deriving (Bounded, Eq, Enum, Ord, Show) data Ou
data Coin = H | T
deriving (Bounded, Eq, Enum, Ord, Show)
data Dice = D1 | D2 | D3 | D4 | D5 | D6
deriving (Bounded, Eq, Enum, Ord, Show)
data Outcome = Win | Lose
deriving (Eq, Ord, Show)
class Monad m => MonadGamble m where
toss :: m Coin
roll :: m Dice
game :: MonadGamble m => m Outcome
game = undefined
然而,我对单子还是新手,我不知道如何与他们合作。例如:游戏定义应该实现我上面解释的游戏,但是我应该如何使用这个赌博单子,例如,执行一个或多个掷骰/掷骰,并获得结果值,以便我可以使用/使用它们
根据我的理解,Monad上总是有两个默认函数:return和(>>=),但我不知道这将如何应用于MonadGable Monad
如果有人能在这方面帮助我,我将不胜感激
致以最良好的祝愿,
Skyfe.首先,
MonadGamble
在技术上不是monad,而是一个扩展monad的类型类,因此它有两个相关联的东西:toss
和roll
,分别表示toss或roll的值。在game
的类型签名中,m
是monad,它是MonadGamble
的一个实例,因此我们可以自动使用toss
和roll
这里可以使用Haskell的do符号。因为我不想做整个作业,所以我不会详细介绍,但下面是如何编写一个单子,测试两次投币是否相同:
twoFlips :: MonadGamble m => m Bool
twoFlips = do
coin1 <- toss
coin2 <- toss
return (coin1 == coin2)
您可以将
MonadGamble
视为一种小型语言,具有四种结构:
do
x <- a
b
这是一个简单的程序,只返回x
toss
这是一个简单的程序,掷硬币一次并返回结果(正面或反面),然后
这是一个简单的程序,可以滚动模具一次并返回结果(六个面之一D1
-D6
)
注意Monad
结构do
和return
也是MonadGamble
语言的结构;这就是Monad m=>
在MonadGamble
声明中的意思
您需要做的是编写一个程序来实现所描述的游戏,使用上面定义的四个“构造”。既然你是单子的新手,你可能想用这四种结构写游戏,考虑如何通过编写你自己的助手函数来简化它,然后看看它给你的助手函数提供了什么名字(我怀疑你需要任何它没有的东西)。
为了让您开始,这里有一个程序可以滚动模具,然后根据结果掷硬币一次或两次:
-- | Roll the die, then if the result is 1-3 flip the coin once, otherwise twice,
-- returning a list of the results.
roller = do
d <- roll
if d `elem` [ D1, D2, D3 ]
then do
c <- flip
return [ c ]
else do
c0 <- flip
c1 <- flip
return [ c0, c1 ]
——|掷骰子,如果结果是1-3,则掷硬币一次,否则两次,
--返回结果列表。
滚筒=do
d您可以编写游戏的整个逻辑,而无需实现MonadGamble
,然后您可以编写实例MonadGamble一些现有的\u monad,其中…
,以获得它运行的实际行为。需要明确的是:在Haskell中,“类型”是(大致)一组值。“类”是一组类型(而不是一组值)。因此,MonadGamble
是一组类型,每个类型都有>=
和返回
操作,加上MonadGamble
操作toss
和roll
。谢谢!我想我应该使用Haskell的结构,它实际上就是
toss
roll
-- | Roll the die, then if the result is 1-3 flip the coin once, otherwise twice,
-- returning a list of the results.
roller = do
d <- roll
if d `elem` [ D1, D2, D3 ]
then do
c <- flip
return [ c ]
else do
c0 <- flip
c1 <- flip
return [ c0, c1 ]