Haskell:使用monad类

use*_*349 3 monads haskell class

作为一项任务,我需要与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
Run Code Online (Sandbox Code Playgroud)

但是我还是Monads的新手,我不知道如何使用它们.例如:游戏定义应该实现我上面解释的游戏,但是我应该如何处理这个Gambling Monad,例如,执行一个或多个抛掷/滚动并获得结果值,以便我可以使用/使用它们吗?

另外根据我的理解,Monad总是有2个默认函数:return和(>> =),但我不知道这将如何适用于MonadGable monad?

如果有人可以帮助我,我非常感谢!

最好的问候,Skyfe.

Jos*_*lin 8

首先,MonadGamble在技​​术上这里不是monad,而是一个扩展monad的类型类,以便它有两个与之相关的东西:toss并且roll,每个都分别表示折腾或滚动的值.在类型签名中game,m是monad,它是一个实例MonadGamble,所以我们自动提供给我们tossroll.

你可以在这里使用Haskell的表示法.我不会详细说明因为我不想完成整个任务,但是这里你可以编写一个monad来测试两个掷硬币是否相同:

twoFlips :: MonadGamble m => m Bool
twoFlips = do
    coin1 <- toss
    coin2 <- toss
    return (coin1 == coin2)
Run Code Online (Sandbox Code Playgroud)

您也可能会发现replicateM函数from 有用Control.Monad,它允许我们重复monadic操作并将结果返回到列表中:

import Control.Monad (replicateM)

tenCoins :: MonadGamble m => m [Coin]
tenCoins = replicateM 10 toss
Run Code Online (Sandbox Code Playgroud)