# 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.

source to share

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

source to share

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

source to share