Lecture 9. Input and output Functional Programming [ Faculty of Science Information and Computing Sciences] 0
Big picture ▶ This course: typed, purely functional programming ▶ Today: purity and impurity [ Faculty of Science Information and Computing Sciences] 1
Goals ▶ Learn the difgerence between pure and impure ▶ Interact with the outside world in Haskell ▶ Input/output ▶ Random generation ▶ Introduce do - and monadic notation through an example Chapter 10 from Hutton’s book [ Faculty of Science Information and Computing Sciences] 2
In this modern era, programs are interactive Respond to user input, more like a dialogue From the perspective of a program, it needs to communicate with an outside world How do we model this in Haskell? Interactive programs ▶ In the old days, all programs were batch programs ▶ Introduce the program and input, sit and drink tea/cofgee for hours, and get the output ▶ Programs were isolated from each other ▶ The part of Haskell your have learnt up to now [ Faculty of Science Information and Computing Sciences] 3
Interactive programs ▶ In the old days, all programs were batch programs ▶ Introduce the program and input, sit and drink tea/cofgee for hours, and get the output ▶ Programs were isolated from each other ▶ The part of Haskell your have learnt up to now ▶ In this modern era, programs are interactive ▶ Respond to user input, more like a dialogue ▶ From the perspective of a program, it needs to communicate with an outside world ▶ How do we model this in Haskell? [ Faculty of Science Information and Computing Sciences] 3
Inlining : is always equivalent to: is always equivalent to: (\x -> ... x ... x ...) e is always equivalent to: let x = e in ... x ... x ... ... e ... e ... ... x ... x ... where x = e Purity = referential transparency Referential transparency = you can always substitute a term by its defjnition without change in the meaning [ Faculty of Science Information and Computing Sciences] 4
let x = e in ... x ... x ... ... e ... e ... ... x ... x ... where x = e Purity = referential transparency Referential transparency = you can always substitute a term by its defjnition without change in the meaning ▶ Inlining : is always equivalent to: is always equivalent to: (\x -> ... x ... x ...) e is always equivalent to: [ Faculty of Science Information and Computing Sciences] 4
Note that the second version duplicates work, but we are speaking here about the meaning of the expression, not its effjciency where xs = filter p ys reverse xs ++ xs reverse (filter p ys) ++ filter p ys Referential transparency A concrete example: is equivalent to: [ Faculty of Science Information and Computing Sciences] 5
where xs = filter p ys reverse xs ++ xs reverse (filter p ys) ++ filter p ys Referential transparency A concrete example: is equivalent to: Note that the second version duplicates work, but we are speaking here about the meaning of the expression, not its effjciency [ Faculty of Science Information and Computing Sciences] 5
Discarding (weakening) if t does not mention x , is equivalent to : Commuting/reordering (exchange) is always equivalent to: let x1 = e; x2 = e in t let x1 = e in t[x1/x2] let x = e in t t let x1 = e1; x2 = e2 in t let x2 = e2; x1 = e1 in t Referential transparency: some consequences ▶ Copying/duplication (contraction) is always equivalent to: [ Faculty of Science Information and Computing Sciences] 6
Commuting/reordering (exchange) is always equivalent to: let x1 = e; x2 = e in t let x1 = e in t[x1/x2] let x = e in t t let x1 = e1; x2 = e2 in t let x2 = e2; x1 = e1 in t Referential transparency: some consequences ▶ Copying/duplication (contraction) is always equivalent to: ▶ Discarding (weakening) if t does not mention x , is equivalent to : [ Faculty of Science Information and Computing Sciences] 6
let x1 = e; x2 = e in t let x1 = e in t[x1/x2] let x = e in t t let x1 = e1; x2 = e2 in t let x2 = e2; x1 = e1 in t Referential transparency: some consequences ▶ Copying/duplication (contraction) is always equivalent to: ▶ Discarding (weakening) if t does not mention x , is equivalent to : ▶ Commuting/reordering (exchange) is always equivalent to: [ Faculty of Science Information and Computing Sciences] 6
This has practical advantages: The compiler can reorder your program for effjciency Expressions are only evaluated (once) when really needed This is called lazy evaluation Paralellism becomes much easier Referential transparency ▶ Referential transparency decouples the meaning of the program from the order of evaluation ▶ Inlining or duplicating does not change the program [ Faculty of Science Information and Computing Sciences] 7
Referential transparency ▶ Referential transparency decouples the meaning of the program from the order of evaluation ▶ Inlining or duplicating does not change the program ▶ This has practical advantages: ▶ The compiler can reorder your program for effjciency ▶ Expressions are only evaluated (once) when really needed ▶ This is called lazy evaluation ▶ Paralellism becomes much easier [ Faculty of Science Information and Computing Sciences] 7
let k = getChar in k == k getChar == getChar Side-efgects Interaction with the world in not referentially transparent! Suppose that getChar :: Char retrieves the next key stroke from the user is always True , whereas this is not the case with We say that getChar is a side-efgectful action ▶ getChar is also called an impure function [ Faculty of Science Information and Computing Sciences] 8
Side-efgects ▶ Many other actions have side-efgects ▶ Printing to the screen ▶ Generate a random number ▶ Communicate through a network ▶ Talk to a database ▶ Intuitively, these actions infmuence the outside world ▶ Key properties: we cannot dicard/duplicate/exchange the world ▶ And thus we cannot substitute for free [ Faculty of Science Information and Computing Sciences] 9
How should we think of World and putChar ? putChar :: Char -> IO type IO = World -> World putChar c world = ... -- details hidden Modelling output Following this idea, we model an action by a function which changes the world Using IO we can give a type to putChar [ Faculty of Science Information and Computing Sciences] 10
putChar :: Char -> IO type IO = World -> World putChar c world = ... -- details hidden Modelling output Following this idea, we model an action by a function which changes the world Using IO we can give a type to putChar How should we think of World and putChar ? [ Faculty of Science Information and Computing Sciences] 10
We introduce reverse composition (f >>> g) x = g (f x) putAB = putChar 'a' >>> putChar 'b' putAB -- also, flip (.) (>>>) :: (a -> b) -> (b -> c) -> a -> c = putChar 'b' . putChar 'a' -- or using composition (putChar 'a' world) putAB world = putChar 'b' putAB :: IO Combining output actions Executing two actions in sequence is plain composition The order is not very intuitive [ Faculty of Science Information and Computing Sciences] 11
putAB = putChar 'a' >>> putChar 'b' putAB -- also, flip (.) (f >>> g) x = g (f x) (>>>) :: (a -> b) -> (b -> c) -> a -> c = putChar 'b' . putChar 'a' -- or using composition (putChar 'a' world) putAB world = putChar 'b' putAB :: IO Combining output actions Executing two actions in sequence is plain composition The order is not very intuitive ▶ We introduce reverse composition [ Faculty of Science Information and Computing Sciences] 11
putStr [] putStr :: String -> IO = id -- keep the world as it is putStr (c:cs) = putChar c >>> putStr cs putStrLn s = putStr s >>> putChar '\n' putStr , fjrst version putStr s prints the whole string to the screen putStrLn s does the same, with a newline at the end [ Faculty of Science Information and Computing Sciences] 12
Solution: pair the output value with the new world What is now the return type of putChar ? We use the empty tuple as a dummy value type IO a = World -> (a, World) getChar :: IO Char getChar = ... -- details hidden putChar :: Char -> IO () Modelling input Our IO type is not suitable for getChar . Why not? Fix? [ Faculty of Science Information and Computing Sciences] 13
We use the empty tuple as a dummy value type IO a = World -> (a, World) getChar :: IO Char getChar = ... -- details hidden putChar :: Char -> IO () Modelling input Our IO type is not suitable for getChar . Why not? Fix? ▶ Solution: pair the output value with the new world What is now the return type of putChar ? [ Faculty of Science Information and Computing Sciences] 13
type IO a = World -> (a, World) getChar :: IO Char getChar = ... -- details hidden putChar :: Char -> IO () Modelling input Our IO type is not suitable for getChar . Why not? Fix? ▶ Solution: pair the output value with the new world What is now the return type of putChar ? ▶ We use the empty tuple as a dummy value [ Faculty of Science Information and Computing Sciences] 13
• Couldn't match expected type ‘Char’ echo = putChar getChar with actual type ‘IO Char’ Combining input and output Suppose that we want to echo a character [ Faculty of Science Information and Computing Sciences] 14
Recommend
More recommend