TCU CoSc 10403 Introduction Programming (with Java) Program Development Environment.
© M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an...
-
Upload
alexina-mosley -
Category
Documents
-
view
215 -
download
0
Transcript of © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an...
![Page 1: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/1.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.1
Programming with actions
Why is I/O an issue?
• I/O is a kind of side-effect. Example:Suppose there is an operationinputInt :: Int -- reads an integer
inputDiff = inputInt – inputInt
inputInt should return two different values (depending on the users input). Hence, its evaluation depends on the context where (or when) it is executed side-effect!!!
• The meaning of an expression relying on side-effects is no longer determined by looking only at the meanings of its parts.
![Page 2: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/2.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.2
Monadic I/O
• The Haskell type IO a is the type of I/O actions of type a, e.g., the elements of a are somehow wrapped into an I/O container; the monad IO.
• An expression of type IO a is a program which will do some I/O and then return a value of type a.
• One way of looking at the I/O a types is that they provide a simple imperative language for writing I/O programs on top of Haskell, without compromising the functional model of Haskell.
• This approach is called the monadic approach. It is more general and can be used to incorporate side-effect into a pure functional programming language (without its problems).
![Page 3: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/3.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.3
Reading input and writing output
getLine :: IO String
getChar :: IO Char
putStr :: String -> IO ()
print :: Show a => a -> IO ()
where () is the type containing exactly one element; the element ().
Remark:In WinGHCi just those I/O actions of type IO () are actually
printed tothe screen.
![Page 4: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/4.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.4
The do notation
The do notation is a flexible mechanism. With respect to the monad IO
it supports two things:• it is used to sequence I/O programs, and• it is used to ‘capture’ the values returned by IO actions and
so to pass these values to actions which follow them in the program.
In general:• it is used to sequence programs wrapped in monad, and• it is used to unwrap the values returned by the monad and so
to pass these values to actions which follow them in the program.
![Page 5: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/5.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.5
Examples
putStrLn :: String -> IO ()
putStrLn str = do putStr str
putStr ”\n”
read2lines :: IO ()
read2lines = do getLine
getLine
puStrLn ”Two lines read.”
getNput :: IO ()
getNput = do line <- getLine
putStrLn line
where line names the result of getLine (local variable).
![Page 6: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/6.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.6
Examples (cont’d)
reverse2lines :: IO ()
reverse2lines = do line1 <- getLine
line2 <- getLine
let rev1 = reverse line1
let rev2 = reverse line2
putStrLn rev1
putStrLn rev2
getInt :: IO Int
getInt = do line <- getLine
return (read line :: Int)
where return :: a -> IO a packs an a value in the IO monad.
![Page 7: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/7.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.7
Examples (cont’d)
Notice, that the following program is not type correct:
getInt = do line <- getLine
(read line :: Int)
Each component of a do construction has to be an element of IO a for a
type a.
while :: IO Bool -> IO () -> IO ()
while test action
= do res <- test
if res then do action
while test action
else return ()
![Page 8: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/8.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.8
Examples (cont’d)
isEOF :: IO Bool
copyInputToOutput :: IO ()
copyInputToOutput
= while (do res <- isEOF
return (not res))
(do line <- getLine
putStrLn line)
![Page 9: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/9.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.9
Examples (cont’d)
goUntilEmpty :: IO ()goUntilEmpty = do line <- getLine if line == [] then return () else (do putStrLn line goUntilEmpty)
goUntilEmpty’ :: IO ()goUntilEmpty’ = do line <- getLine while (return (line /= [])) (do putStrLn line line <- getLine return ())
does not work since variables cannot be updated.
here we create a new variable
![Page 10: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/10.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.10
Calculator example
data Expr = Lit Int | Var Var | Op Ops Expr Expr
data Ops = Add | Sub | Mul | Div | Mod
type Var = Char
initial :: Store
value :: Store -> Var -> Int
update :: Store -> Var -> Int -> Store
data Command = Eval Expr | Assign Var Expr | Null
commLine :: String -> Command
eval :: Expr -> Store -> Int
![Page 11: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/11.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.11
Calculator example (cont’d)
command :: Command -> Store -> (Int,Store)
command Null st = (0 , st)
command (Eval e) st = (eval e st , st)
command (Assign v e) st = (val , newSt)
where val = eval e st
newSt = update st v val
calcStep :: Store -> IO Store
calcStep st
= do line <- getLine
comm <- return (commLine line)
(val , newSt) <- return (command comm st)
print val
return newSt
![Page 12: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/12.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.12
Calculator example (cont’d)
calcSteps :: Store -> IO ()
calcSteps st = while notEOF
(do newSt <- calcStep st
calcSteps newSt)
notEOF :: IO Bool
notEOF = do res <- isEOF
return (not res)
mainCalc :: IO ()
mainCalc = calcSteps initial
![Page 13: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/13.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.13
Further I/O
• File I/O– readFile :: FilePath -> IO String– writeFile :: FilePath -> String -> IO ()– appendFile :: FilePath -> String -> IO ()
• Errors– ioError :: IOError -> IO a– catch :: IO a -> (IOError -> IO a) -> IO a
where IOError is the system-dependent data type of I/O errors. More on
error handling (especially the type IOError) can be found in the documentation for the I/O library IO.hs.
![Page 14: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/14.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.14
Monads
IO is a type constructor, i.e., an operation on types. It maps a type a to the
type IO a of I/O action on a.
A characteristic of the I/O monad is that it allows to sequence operations.
do line <- getLine putStrLn line
What is the type of such a combinator which sequences the operations:
(>>=) :: IO a -> (a -> IO b) -> IO b
or, more general, for an arbitrary type constructor m, a combinator
(>>=) :: m a -> (a -> m b) -> m b
![Page 15: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/15.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.15
Monads (cont’d)class Monad m where
(>>=) :: m a -> (a -> m b) -> m breturn :: a -> m a(>>) :: m a -> m b -> m b
fail :: String -> m am >> k = m >>= \_ -> kfail s = error s
Requirements (informally):• The operation return x should simply return the value x,
without any additional computational effect.• The sequencing given by >>= should be irrelevant of the way
that expressions are bracketed.• >> acts like >>=, except that the value returned by the first
expression is discarded rather than being passed to the second argument.
• The value fail s corresponds to a computation that fails, giving the error message s.
![Page 16: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/16.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.16
Rules for monads
(>@>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> mc)
f >@> g = \x -> (f x) >>= g
Rules that should be satisfied:(M1) return >@> f = f identity law (left)(M2) f >@> return = f identity law
(right)(M3) (f >@> g) >@> h = f >@> (g >@> h) associativity
In terms of (>>=):(M1) (return x) >>= f = f x
(M2) m >>= return = m
(M3) (m >>= f) >>= g = m >>= (\x -> (f x) >>= g)
In category theory (>@>) is called the Kleisli composition.
![Page 17: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/17.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.17
The do notation revisited
The do notation can be used for arbitrary monads (not just for the I/O monad). It just a shorthand for an expression build up from (>>=)
and (>>).
Example:
do line <- getLine putStrLn line putStrLn ”That’s it.” return 5
is translated to
getLine >>= putStrLn >> putStrLn ”That’s it.”>> return 5
![Page 18: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/18.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.18
Examples of monads
• Identity monad– m a = a– m >>= f = f m– return = id
• I/O monad• List monad
instance Monad [] wherexs >>= f = concat (map f xs)return x = [x]fail s = []
• Maybe monad (Error monad)instance Monad Maybe where
(Just x) >>= k = k xNothing >>= k = Nothingreturn = Justfail s = Nothing
![Page 19: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/19.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.19
Examples of monads (cont’d)
• Parsing monad (Parsec – a useful parser combinator library)– Import statement: import
Text.ParserCombinators.Parsec
The type GenParser a state b• is the type of parsers taking lists of a elements as input
producing an element of b.• is implemented similar to the type Parser from Week 7.• has a parameter state. This parameter can be used as an
internal state storing information during the parsing process.• has an internal and hidden error state. This state is used to
keep track of errors that occurred during the parsing process.GenParser combines 3 monadic structures (parser monad, state
monad, error monad) into one data structure.
![Page 20: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/20.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.20
Examples of monads (cont’d)
• State monad– a state monad is a type of the form State a b = a ->
(a,b) where the type constructor is State a.– An operation of this type can change the state (of type a)
before returning a value of type b.– Example:
data Tree a = Nil | Node a (Tree a) (Tree a)
Moon
Dweezil
Ahmet
Ahmet
Moon
0
2
1
1
0
![Page 21: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/21.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.21
Examples of monads (cont’d)
type Table a = [a]
data State a b = State (Table a -> (Table a , b))
instance Monad (State a) where
return x = State (\tab -> (tab,x))
(State st) >>= f = State (\tab -> let
(newTab,y) = st tab
(State trans) = f y
in trans newTab)
![Page 22: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/22.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.22
Examples of monads (cont’d)
numberTree :: Eq a => Tree a -> State a (Tree Int)
numberTree Nil = return Nil
numberTree (Node x t1 t2) = do num <- numberNode x
nt1 <- numberTree t1
nt2 <- numberTree t2
return (Node num nt1 nt2)
numberNode :: Eq a => a -> State a Int
numberNode x = State (nNode x)
nNode :: Eq a => a -> (Table a -> (Table a , Int))
nNode x table | elem x table = (table , lookup x table)
| otherwise = (table++[x] , length table)
![Page 23: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/23.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.23
Examples of monads (cont’d)
extract :: State a b -> b
extract (State st) = snd (st [])
numTree :: Eq a => Tree a => Tree Int
numTree = extract . numberTree
![Page 24: © M. Winter COSC 4P41 – Functional Programming 9.19.1 Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.](https://reader035.fdocuments.net/reader035/viewer/2022070403/56649f2a5503460f94c43ee8/html5/thumbnails/24.jpg)
© M. Winter
COSC 4P41 – Functional Programming
9.24
Some Monad Functions
Module Prelude
• readFile :: FilePath -> IO String• sequence :: Monad m => [m a] -> m [a] • sequence_ :: Monad m => [m a] -> m () • mapM :: Monad m => (a -> m b) -> [a] -> m [b] • mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
Module Data.IORef (updatable varibles, i.e., a state monad)• newIORef :: a -> IO (IORef a)• readIORef :: IORef a -> IO a• writeIORef :: IORef a -> a -> IO ()