[英]Haskell : Working with monad classes
作为一项任务,我需要与Haskell中的monad一起工作并创建一个赌博游戏,其中有一个简单的规则:投掷6个硬币,计算头部,掷骰子,如果其结果等于或大于计算的头数,则获胜,否则你输了。 我获得了以下定义赌博Monad的“框架”:
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
但是我还是Monads的新手,我不知道如何使用它们。 例如:游戏定义应该实现我上面解释的游戏,但是我应该如何处理这个Gambling Monad,例如,执行一个或多个抛掷/滚动并获得结果值,以便我可以使用/使用它们吗?
另外根据我的理解,Monad总是有2个默认函数:return和(>> =),但我不知道这将如何适用于MonadGable monad?
如果有人可以帮助我,我非常感谢!
最好的问候,Skyfe。
首先, MonadGamble
在技术上并不是一个monad,而是一个扩展monad的类型类,因此它有两个与之相关的东西: toss
和roll
,分别表示折腾或滚动的值。 在game
的类型签名中, m
是monad,它是MonadGamble
一个实例,所以我们自动可以toss
和roll
。
你可以在这里使用Haskell的表示法。 我不会详细说明因为我不想完成整个任务,但是这里你可以编写一个monad来测试两个掷硬币是否相同:
twoFlips :: MonadGamble m => m Bool
twoFlips = do
coin1 <- toss
coin2 <- toss
return (coin1 == coin2)
您还可以从Control.Monad
找到有用的replicateM
函数,它允许我们重复monadic操作并将结果返回到列表中:
import Control.Monad (replicateM)
tenCoins :: MonadGamble m => m [Coin]
tenCoins = replicateM 10 toss
您可以将MonadGamble
视为一种迷你语言,具有以下四种结构:
do
x <- a
b
运行程序a
后跟程序b
(其中,在b
,变量x
指的是a
的结果),
return x
这是一个只返回x
的简单程序,
toss
这是一个简单的程序,翻转硬币一次并返回结果(头或尾),和
roll
这是一个简单的程序,它将模具滚动一次并返回结果(六个面D1
- D6
)。
请注意, Monad
构造do
和return
也是MonadGamble
语言的构造; 这就是Monad m =>
在MonadGamble
宣言中的MonadGamble
。
你需要做的是使用上面定义的四个'构造'编写一个实现所描述游戏的程序。 由于你是monad的新手,你可能只想使用这四种结构编写游戏,考虑如何通过编写自己的帮助函数来简化游戏,然后查看标准的Monad库 ,看看它为你的助手提供了什么名称功能(我怀疑你需要它没有的东西)。
为了让你开始,这里有一个程序可以掷骰子然后翻转一两次硬币,具体取决于结果:
-- | 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 ]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.