Implement the factorial function in the io monad

Assignment Help Programming Languages
Reference no: EM13854652

import Data.Array
import Data.IORef (newIORef, readIORef, writeIORef)

You will need to consult the documentation on the imported modules.

Please note: ghci will evaluate expressions, of course, but if the expression is of type (IO a), its value will be *executed* and the resulting value in type a showed.

QUESTION 1

Use imperative-style programming to implement the factorial function in the IO monad. In other words, create and initialize variables (references) using newIORef, modify their values using a while loop with ,readIORef and writeIORef, then have the IO action return a pair consisting of the input (n) and the final result. The expression named mod3 below gives a small example of this kind of programming.

Reading:
- LYAH Chapter 9 "Input and Output" up to the first occurrence of "Control.Monad".
- Module documentation for the functions imported from Data.IORef (see the top of this file).

-}

while :: IO Bool -> IO () -> IO ()
while test body =
do b <- test
if b
then do {body ; while test body} -- same-line syntax for do
else return ()

-- remainder when integer-dividing n by 3
mod3 :: Integer -> IO Integer
mod3 n = do r <- newIORef n
while
(do {v <- readIORef r; return (v >= 3)})
(do {v <- readIORef r; writeIORef r (v-3)})
readIORef r

-- ghci> fact 4
-- 24
fact :: Integer -> IO (Integer, Integer)
fact n =
do
undefined

{- CODE FOR QUESTIONS 2 AND 3

Below we give a roll-your-own alternative to Data.IORef. We model memory as an array and memory locations (references) as indices into the array. Using this model it is straightforward to implement creation, reading and writing of references.

However, as with the IO monad, we use a layer of abstraction to hide all the details of memory management. Instead of (IO a), we will have (MM a) -- "MM" for "memory modifiers".

The implementation of actions in (IO a) is completely hidden from us in Haskell. The actions in (MM a) will all be constructed from scratch using the usual kinds of Haskell data. The basic decision in designing MM is how represent actions.

Since we're focusing on references, it's natural to consider an action as something, that in addition to producing a value, modifies memory.

Modifying something in a functional setting is done by applying a function which produces the new "modified" copy. Thus an action can be thought of as a function that takes a memory (array), and from it produces both a value and a new memory (an array with possibly some values updated).

More formally, actions in (MM a) are elements of the type

Mem -> (Mem,a)

so we define

data MM a = MM (Mem -> (Mem, a))

We want to use the same "do" syntax to hide memory management details that IO does. Fortunately, it turns out that MM is a monad.

The definition of (>>=) for MM is not immediately transparent, but it need not be to do Question 2. For question 2, MM can be thought of as replacement for IO and programs using "do" can be constructed analogously. Question 3 requires understanding details of the construction of MM and its operations.

-}

-- for convenience
type Z = Integer

-- raise an error if an attempt to index the array is out of bounds
checkBounds :: String -> Z -> Array Z a -> ()
checkBounds msg i a =
let (lower, upper) = bounds a
in if i >= lower && i < upper
then ()
else error msg

-- Memory is modeled by (Mem n i a) where:
-- - n is the size of the memory (number of locations)
-- - a is an array, with indexes 0<=i<n, representing the
-- values stored in memory and
-- - i is the next position to allocate at
data Mem = Mem Z Z (Array Z Z)
deriving Show

-- A reference is an index into the memory array.
type Ref = Z

-- Memory-modifying computations with result type a.
data MM a = MM (Mem -> (Mem, a))

-- ignore, not needed for either question!
instance Functor MM where
fmap f (MM g) = MM (\m -> let (m',v) = g m in (m', f v))

-- ignore, not needed for either question!
instance Applicative MM where
pure x = MM (\m -> (m,x))
MM f <*> MM g =
MM (\m-> let (m', f') = f m
(m'', x) = g m'
in (m'', f' x))

instance Monad MM where

-- action that produces x without modifying memory
return x = MM (\m -> (m,x))

-- like composing f and g, except memory modifications are chained
(MM a) >>= f =
MM (\m-> let (m', v) = a m
MM b = f v
in b m')

-- create an initial memory of size n
initMem :: Z -> Mem
initMem n = Mem n 0 (array (0,n) [])

-- return a new reference, initialized to v
newRef :: Z -> MM Ref
newRef v =
MM f where
f (Mem n i a) = (m', i )
where m' = Mem n (i+1) a'
a' = a // [(i,v)]

writeRef :: Ref -> Z -> MM ()
writeRef j v =
MM f where f (Mem n i a) = (Mem n i a', ())
where a' = a // [(j,v)]

readRef :: Ref -> MM Z
readRef j =
MM f where f m@(Mem _ _ a) = (m, a!j)

run :: Z -> MM a -> a
run n (MM mm) =
snd $ mm (initMem n)

-- run the action and return a list of memory contents
runDump :: Z -> MM a -> [Z]
runDump n (MM mm) =
elems a where
Mem _ _ a = fst $ mm (initMem n)

-- The test needs to be in MM Bool instead of just Bool because it
-- will generally need to refer to values stored in memory.
while' :: MM Bool -> MM () -> MM ()
while' test body =
do b <- test
if b
then do {body ; while' test body}
else return ()

{- QUESTION 2

Repeat Question 1, but using MM and its reference operations in place of IO, and while' in place of while. You can execute elements of (MM a) using the run function above (which also takes an argument for the size of memory to use).

ghci> run 10 (fact' 4)
24

-}

fact' :: Integer -> MM (Integer, Integer)
fact' n =
do undefined

{- QUESTION 3 -- EXTRA CREDIT

Implement versions of newRef, writeRef and readRef that, instead of returning a single reference, allocate a pair of consecutive storage locations and return the first address (index). Effectively, the operations deal with 2-cell objects. The advantage of this is that linked structures, like linked lists, can be implemented.

Below is given the types for the new operations, and a program appendTest that creates two linked lists then appends them by changing the pointer at the end of the first list. The example uses some auxiliary functions. You just need to implement the three reference operations.

-}

newRef2 :: Z -> Z -> MM Ref
newRef2 u v =
undefined

writeRef2 :: Ref -> Z -> Z -> MM ()
writeRef2 j u v =
undefined

readRef2 :: Ref -> MM (Z,Z)
readRef2 j =
undefined

mkList :: [Z] -> MM Ref
-- Use -1 for "nil", i.e. null pointer
mkList [] = return (-1)
mkList (x:xs) =
do tail <- mkList xs
head <- newRef2 x tail
return head

append :: Ref -> Ref -> MM (Ref)
-- x and y must be pointers to lists
append (-1) y = return y
append x y =
do append' x
return x
where append' x =
do (v,i) <- readRef2 x
if i == -1
then writeRef2 x v y
else append' i

collectList :: Ref -> MM [Z]
collectList (-1) = return []
collectList i =
do (x,j) <- readRef2 i
xs <- collectList j
return (x:xs)

-- ghci> run 37 appendTest
-- [1,2,3,4,5,6]
appendTest :: MM [Z]
appendTest =
do l <- mkList [1,2,3]
newRef 17 >> newRef 17 >> newRef 17 -- some irrelevant creations
l' <- mkList [4,5,6]
newRef 17 >> newRef 17 >> newRef 17 -- ditto
x <- append l l'
result <- collectList x
return result

Reference no: EM13854652

Questions Cloud

Advantages and disadvantages of organizations structure : What are the advantages and disadvantages of the organization's structure? What specific problems is your health care organization facing or likely to face? What is your role in solving these issues?
The hidden costs of absenteeism and sick leave : Never Say Never Industries, a 2300-employee firm, has a serious and growing absenteeism problem.  Last year the total  employee-hours lost to absenteeism came to 134,607.
Comments by twiggy forrest regarding iron ore production : Consider the iron ore production industry, and assume that there are just two producers, FM and BHP. Initially assume that both firms are identical in terms of their production costs. If the two firms can cooperate, what should they do in order to..
Identify the most complex user-system interaction : Identify the most complex user-system interaction (input/response couplet) within the normal flow (ie the step with the most number of side effects, or most complex internal logic), and produce an operation contract for that input-response couplet..
Implement the factorial function in the io monad : Use imperative-style programming to implement the factorial function in the IO monad. In other words, create and initialize variables (references) using newIORef, modify their values using a while loop with ,readIORef and writeIORef, then have th..
What is effect of stock dividend on corporations stockholder : What is the effect of a stock dividend on a corporation's stockholders' equity accounts? Which would you rather receive as a stockholder - a cash dividend or a stock dividend? Why?
Result in loss of personal information : Question 1. Social media sites result in loss of personal information because
Determine the federal income tax for 2013 : Determine the Federal income tax for 2013 for the Deans on a joint return - Under the divorce decree, John was obligated to pay alimony and child support?
Determine the effect of adrians gross income : What would be the tax consequences of each of the alternatives assuming that Fran currently deducts the mortgage interest on her tax return -  Determine the effect of Adrians gross income for 2014 & 2015.

Reviews

Write a Review

Programming Languages Questions & Answers

  Write program to accept specific team criteria

Here is the initial list of functional requirements: The program should be able to: Accept specific team criteria, Accept specific player criteria,Match players to teams based on criteria specified.

  Summary of the technical experiences that you used

Create the logic for a program that accepts input values for the projected cost of a vacation and the number of months until vacation. A summary of the technical experiences that you used in completing this lab. The commands that were of greatest be..

  Write a little man program that adds a column of input value

Write a Little Man program that adds a column of input values and produces the sum as output. An input value of zero will indicate the last value in the input stream of input values.

  Statements to find array elements are null or not

Write down statements needed to find whether any of the array elements are null or refer to the empty String. Set the variable hasEmpty to true.

  Implement a program to learn vocabulary of foreign languages

We want to implement a program which will help students learn the vocabulary of foreign languages. The first step, which has been assigned to you, is to build a data structure representing a list of English words and their translation in a foreign..

  Write function which takes string as its input

In this, you are required to write the function which takes string as its input, chops sentence into words, and for each word, capitalizes the rst letter

  Create program to calculate and display number of miles

Create a program to calculate and displays the number of miles per hour over the speed limit that a speeding driver was doing. The program should ask for the speed limit and the drivers speed.

  Draw a state transition diagram for garage door system

Draw a state transition diagram for garage door system - Design a PLC program using ladder logic that has two input and three outputs.

  Program-calculate power loss-transmitted-power generating

Write a program to calculate power loss in transmission line with resistance of 0.05 ohms/mile. Calculate power loss if 500 kW of power is transmitted from power generating station.

  Program to compute risk of weight-related health problems

A quantity known as the body mass (BMI) is used to calculate the risk of weight-related health problems. Write a program that accepts weight and height and then displays the BMI value and Status.

  Compute the area of a circle

In MIPS assembly, write an assembly language program which asks a user for a decimal number, converts it to hex, prints the result.

  Characteristics used for biometric user authentication

You have just been promoted to manager of computer security for large enterprise (XYZ Corporation). Your first project as security manager is to estimate principal physical characteristics used for biometric user authentication.

Free Assignment Quote

Assured A++ Grade

Get guaranteed satisfaction & time on delivery in every assignment order you paid with us! We ensure premium quality solution document along with free turntin report!

All rights reserved! Copyrights ©2019-2020 ExpertsMind IT Educational Pvt Ltd