Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
29 views3 pages

Monads Lab

This document describes two Haskell exercises involving monads. The first exercise involves defining the Expr data type as a monad and using it to implement functions for replacing variables and converting expressions. The second exercise involves modeling randomness using the State monad by rewriting a dice rolling program to explicitly manage the random seed.

Uploaded by

jdkdjs
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views3 pages

Monads Lab

This document describes two Haskell exercises involving monads. The first exercise involves defining the Expr data type as a monad and using it to implement functions for replacing variables and converting expressions. The second exercise involves modeling randomness using the State monad by rewriting a dice rolling program to explicitly manage the random seed.

Uploaded by

jdkdjs
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 3

Haskell exercise: Monads

Department of Mathematics and Computer Science


University of Southern Denmark
October 25, 2017

1. The Maybe-monad, and a monad for Expr


You are given a data type for expressions:

data Expr a = Var a | Add (Expr a) (Expr a) deriving Show

1. To turn Expr into a monad, we should give valid definitions for return
and bind:

return :: a → Expr a
(>>=) :: Expr a → (a → Expr b) → Expr b

Fill out the function bodies with appropriate definitions:

instance Monad Expr where


return x =⊥
(Var a) >>= f = ⊥
(Add x y) >>= f = ⊥

2. We would like to define a function

replace :: Eq a ⇒ [(a, b)] → Expr a → Expr (Maybe b)

which replaces occurences of type a with something of type Maybe b.


Example:

• replace [ ] (Var ’a’) = Var Nothing


• replace [(’a’, 3)] (Var ’a’) = Var (Just 3)

1
• replace [(’a’, 3)] (Add (Var ’a’) (Var ’b’)) = Add (Var (Just 3)) (Var Nothing)

You should use the functionality of the Expr -monad to implement


replace. You can use

lookup :: Eq a ⇒ a → [(a, b)] → Maybe b

from the Prelude in your implementation of replace.

3. Now we would like to make a function

convert :: Expr (Maybe a) → Maybe (Expr a)

which returns Nothing if there is an occurrence of Nothing inside the


input expression e, otherwise it returns Just e 0 , where e 0 is a new
expression where the internal values of type a are not wrapped in Just.
You should use the functionality of the Maybe monad to implement
your convert function.

2. Random numbers and the State Monad


Functions involving randomness in Haskell take a seed g :: StdGen as input,
and returns an output and a new seed g 0 :: StdGen.
As an example, the built-in function

randomR :: (Int, Int) → StdGen → (Int, StdGen)

on inputs randomR (a, b) g, returns (x , g 0 ) (an integer x and a new seed g 0 ),


where x is chosen uniformly, with the condition a 6 x 6 b.
To get a random seed, one needs the IO environment.
A complete program to simulate two die rolls and return the sum of the
die-values is given below. Make sure that you understand how this works,
before going on to the rest of the exercise.

import System.Random
die6 :: StdGen → (Int, StdGen)
die6 g = randomR (1, 6) g
twoDie :: StdGen → (Int, StdGen)
twoDie g = let (d1 , g 0 ) = die6 g
(d2 , g 00 ) = die6 g 0
in (d1 + d2 , g 00 )
test :: IO (Int, StdGen)

2
test = do g ← newStdGen
return (twoDie g)

We would like to give a nicer definition for twoDie which does not explic-
itly handle the random seed.
The State-monad libary provides the following functions to wrap and
unwrap functions in the state monad.

state :: (s → (a, s)) → State s a


runState :: State s a → s → (a, s)

You are provided the following stub of a program:

import Control .Monad .State


die6 0 :: State StdGen Int
die6 0 = ⊥
twoDie 0 :: State StdGen Int
twoDie 0 = ⊥
test 0 :: IO (Int, StdGen)
test 0 = do g ← newStdGen
return (runState twoDie 0 g)

1. Using the function state and your definition die6 , provide a definition
of die6 0 .

2. Implement twoDie 0 only referring to die6 0 and the monadic functional-


ity of State Monad.

You might also like