Haskell: working with monads

As an assignment, I need to work with monads in Haskell and create a gambling game that has one simple rule: roll 6 coins, count heads, roll a dice and if its result is equal to or greater than the number of heads counted, you will win. otherwise you will lose. I was given the following "structure" defining the gambling 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

      

However I am still new to Monads and I have no idea how to work with them. For example: the game definition should implement the game described above, but how do I work with this Monarchy of Gambling to, for example, execute one or more rolls / rolls and get the resulting values, can I use / work with them?

Also from my understanding Monad always has two default functions: return and (-> =), but I don't see how this applies to MonadGable monad?

If anyone can help me it is greatly appreciated!

Regards, Skyfe.

+3


source to share


2 answers


First, MonadGamble

here is technically not a monad, but a style class that extends the monad so that it has two things related to it: toss

and roll

, each of which denotes a value to cast or toss respectively, In a type signature game

, m

is a monad, and it is an instance MonadGamble

so we automatically access us toss

and roll

.

You can use Haskell notation here. I won't go into details because I don't want to do the whole job, but here's how you could write a monad that checks if two coins are the same:

twoFlips :: MonadGamble m => m Bool
twoFlips = do
    coin1 <- toss
    coin2 <- toss
    return (coin1 == coin2)

      



You can also find a useful function replicateM

from Control.Monad

that allows us to repeat the monadic action and return the results to a list:

import Control.Monad (replicateM)

tenCoins :: MonadGamble m => m [Coin]
tenCoins = replicateM 10 toss

      

+8


source


You can think of it MonadGamble

as a mini-language with four constructs:

do
    x <- a
    b

      

which runs the program a

, followed by the program b

(where in the b

variable x

refers to the result a

),

return x

      

it is a simple program that simply returns x

,

toss

      

is a simple program that flips a coin once and returns the result (heads or tails), and



roll

      

it is a simple program that rolls the die once and returns the result (one of six faces D1

- D6

).

Note that Monad

do

and return

are also language constructs MonadGamble

; this is what the Monad m =>

declaration means MonadGamble

.

What you need to do is write a program that implements the described game using the four "constructs" defined above. Since you are new to monads, you probably want to write a game using only these four constructs, consider how you can simplify it by writing your own helper functions, and then look at the standard monad library to see what the names it gives for your helper functions (I doubt you need something that it doesn't have).

For starters, here's a program that rolls a die and then flips a coin once or twice, depending on the outcome:

-- | 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 ]

      

+4


source







All Articles