Presentation is loading. Please wait.

Presentation is loading. Please wait.

Cse536 Functional Programming 1 6/24/2015 Lecture #4, Oct 6, 2004 Reading Assignments –Begin Reading chapter 3 (Simple Graphics) of the Text Homework Assignment.

Similar presentations


Presentation on theme: "Cse536 Functional Programming 1 6/24/2015 Lecture #4, Oct 6, 2004 Reading Assignments –Begin Reading chapter 3 (Simple Graphics) of the Text Homework Assignment."— Presentation transcript:

1 Cse536 Functional Programming 1 6/24/2015 Lecture #4, Oct 6, 2004 Reading Assignments –Begin Reading chapter 3 (Simple Graphics) of the Text Homework Assignment 2 –exercises 2.1 and 2.2 pp. 25 of the text –exercises 2.5 pp. 33 of the text Today’s Topics –Home work solutions to assignment #1 – Program Manipulation – Comparing the functional paradigm –Actions and Haskell –Monads –Simple Graphics

2 Cse536 Functional Programming 2 6/24/2015 Home work solutions First Recursively Second by combining functions Write a function: strlen which returns the length of a string. e.g. strlen "abc" --> 3 strlen "" --> 0 strlen :: String -> Int strlen [] = 0 strlen (x:xs) = 1 + strlen xs strlenA = length strlenB = sum. map (const 1) strlenC = foldr (+) 0. map (const 1)

3 Cse536 Functional Programming 3 6/24/2015 Factorial Write a function which computes n factorial. E.g. fact 0 --> 1 fact 3 --> 6 fact 5 --> 120 factA 0 = 1 factA n = n * (factA (n-1)) factB n = product [1..n]

4 Cse536 Functional Programming 4 6/24/2015 ncopies Write the ncopies function. For example: ncopies 3 5 --> [5,5,5] ncopies 4 "a" --> ["a","a","a","a"] ncopies 0 True --> [] ncopiesA :: Num a => a -> b -> [b] ncopiesA 0 x = [] ncopiesA n x = x : (ncopiesA (n-1) x) ncopiesB n x = map (const x) [1..n] ncopiesC n x = [ x | y <- [1..n] ] ncopiesD n x = take n (repeat x)

5 Cse536 Functional Programming 5 6/24/2015 Power Write the power function for integers. For example: power 5 2 --> 25 power 3 3 --> 27 power 2 5 --> 32 powerA x 0 = 1 powerA x 1 = x powerA x n = x * (powerA x (n-1)) powerB x n = product (ncopies n x)

6 Cse536 Functional Programming 6 6/24/2015 String to Integer 7) Write a function which converts a string of digits into an Int. You will need the following predefined function: ord ‘1’ --> 49 Char to its ascii code follow the following "pipeline" analysis when defining your function "167" --> ['1','6','7'] --> [49,54,55] --> [1,6,7] --> [(1,100),(6,10),(7,1)] --> [100, 60, 7] --> 167 (hint: the first function in the pipeline is very simple. why?)

7 Cse536 Functional Programming 7 6/24/2015 String to Int (cont) Then str2int is an easy composition str2int :: String -> Int str2int = sum. map (uncurry (*)). explist. map (\ z -> z -(ord '0')). map ord The Key is the function explist explist [5,3,4] --> [(5,100),(3,10),(4,1)] How many lists are traversed?

8 Cse536 Functional Programming 8 6/24/2015 Key Function Explist Useful intermediates reverse [1,10,100] [1,10,100] --> [100,10,1] zip [3,4] [100, 10, 1] --> [(3,100), (4,10)] Definition explist zs = zip zs [ power 10 x | x <- reverse [0.. n-1] ] where n = length zs

9 Cse536 Functional Programming 9 6/24/2015 Another explist explist = fst. foldr g ([],1) where z `g` (zs,n) = ((z,n) : zs, n * 10) Suppose we start with [5,3,2] Folding g leaves –5 `g` (3 `g` (2 `g` ([],1))) –5 `g` (3 `g` ((2,1):[],10)) –5 `g` (3 `g` ([(2,1)],10)) –5 `g` ((3,10):[(2,1)],100) –5 `g` ([(3,10),(2,1)],100) –([(5,100),(3,10),(2,1)],1000)

10 Cse536 Functional Programming 10 6/24/2015 Program Manipulation Substitution of equals for equals. if name: f x = e is a definition or a theorem, then we can replace ( f n) with e[n/x] wherever ( f n ) occurs. –name: is the name of the definition or theorem for reference in the proof. –e[n/x] means e with all free occurrences of x replaced by n For example consider: comp: (f. g) x = f (g x) Now prove that ((f. g). h) x = (f. (g. h)) x

11 Cse536 Functional Programming 11 6/24/2015 Proof Pick one side of the equation and transform using rule comp: above ((f. g). h) x = by comp: (left to right) (f. g) (h x) = by comp: (left to right) f (g (h x)) = by comp: (right to left) f ((g. h) x) by comp: (right to left) (f. (g. h)) x

12 Cse536 Functional Programming 12 6/24/2015 Side Effects and Haskell All the Haskell programs we have seen so far have no side-effects. This means that every expression has only one value, no matter where it occurs in the program. This is the basis for the “substitution of equals for equals” rule. Real programs side effect the world. How do we reconcile these two competing properties? Separate the “pure” world, from the “actions” –In syntax »do syntax implies a possible action –Using types. »An expression with a Monadic type (IO a) has possible actions associated with its execution.

13 Cse536 Functional Programming 13 6/24/2015 Comparative Styles Comparing imperative programming with the functional style: data Bintree a = Lf a | (Bintree a) :/\: (Bintree a) Consider the function that updates the left most leaf of a tree. –Imperative code loops down the nodes and makes the change in place. –Functional code makes a copy old the old structure, with minimal changes. –Imperative code is less resource hungry since it doesn't allocate as much –In functional programming it is always "safe" for trees to share sub trees.

14 Cse536 Functional Programming 14 6/24/2015 Example Functional Code leftmost :: a -> Bintree a -> Bintree a leftmost new (Lf x) = Lf new leftmost new (x :/\: y) = (leftmost new x) :/\: y Consider: replace :: Eq a => a -> a -> Bintree a -> Bintree a replace new old (Lf x) = if x==old then Lf new else Lf x replace new old (x :/\: y) = (replace new old x) :/\: (replace new old y) This function copies the whole tree even if doesn't need to. How can we get around this?

15 Cse536 Functional Programming 15 6/24/2015 Less Resource Hungry? replace' :: Eq a => a -> a -> Bintree a -> Bintree a replace' new old w = let replace2 (Lf x) = if x==old then (Lf new,True) else (Lf x,False) replace2 (x :/\: y) = (case (replace2 x,replace2 y) of ((a,False),(b,False)) -> (x :/\: y, False) ((a,True),(b,False)) -> (a :/\: y,True) ((a,False),(b,True)) -> (x :/\: b,True) ((a,True),(b,True)) -> (a :/\: b,True)) in fst(replace2 w)

16 Cse536 Functional Programming 16 6/24/2015 Questions to answer Does this really help? since it still constructs the tree, but then only throws it away. Or does it? What about lazy evaluation? But is it any more efficient? ? t1 (Lf 4 :/\: Lf 6) :/\: (Lf 8 :/\: Lf 12) (12 reductions, 83 cells) ? replace 99 7 t1 (Lf 4 :/\: Lf 6) :/\: (Lf 8 :/\: Lf 12) (22 reductions, 94 cells) ? replace' 99 7 t1 (Lf 4 :/\: Lf 6) :/\: (Lf 8 :/\: Lf 12) (27 reductions, 124 cells) May Be there is something to destructive update. How can we add assignments without ruining all the nice properties of functional languages?

17 Cse536 Functional Programming 17 6/24/2015 Actions It is sometimes useful for a functional program to perform some action (or have some side effect) –Update a piece of state (assignment) –do some IO –draw graphics on a display –return an exception rather than an answer How do we model this? –We use a Monad –A Monad is a type constructor which has an implied action. –For example: IO Int is an action which performs some IO and then returns an Int

18 Cse536 Functional Programming 18 6/24/2015 Sample Effects or Actions –State »Update a piece of the store (assignment) as well as return a final value. –Exceptional cases »There may be an error instead of a final value –Non-determinism »There may be multiple possible final values –Partial Computation »There may be nothing: no final value, or anything else –Communication »There may be external influence on the computation »Perform some Input or Output, as well as a final value. »Draw graphics on a display

19 Cse536 Functional Programming 19 6/24/2015 A Monad uses types to separate Actions (with effects) from pure computations –A Monad is a type constructor which has an implied action. –For example: a computation with type (IO Int ) »is an action which might perform some IO and which then returns an Int –Computations with non-monadic types cannot have any effects. They are pure computations. The user (and the compiler) can rely on this.

20 Cse536 Functional Programming 20 6/24/2015 A monad orders effects A Monad specifies which effects come before others. The “do” operator provides this control over the order in which computations occur do { var <- location x -- the first action ; write var (b+1) -- the next action }

21 Cse536 Functional Programming 21 6/24/2015 Do syntactic sugar do { a; b } = do { _ <- a; b } do { x <- a ; do { y <- b ; do { z <- c ; d }}} = do {x <- a; y <- b; z <- c; d } = do x <- a y <- b z <- c d -- uses indentation -- rather than ;

22 Cse536 Functional Programming 22 6/24/2015 Do: syntax, types, and order IO Int Int semi colons separate actions, good style to line ; up with opening { and closing } last action must must have type Io a which is the type of do cannot have v <-... actions without v <-... must have type IO () do { x <- f 5 ; y <- g 7 ; putChar y ; return (x + 4) }

23 Cse536 Functional Programming 23 6/24/2015 Monads have Axioms Order matters (and is maintained by Do ) do { x <- do { y <- b; c } ; d } = do { y <- b; x <- c; d } Return introduces no effects do { x <- Return a; e } = e[a/x] do { x <- e; Return x } = e

24 Cse536 Functional Programming 24 6/24/2015 Example Monads IO a –Perform an IO action (like read or write to a file or stdin or stdout) and then return an item of type: a GUI a –Perform a GUI action (like draw a pull-down menu) and then return an item of type: a State t a –Perform an action which could change the value of a mutable variable (like an assignment) in a state thread t, and then return an item of type: a Parser a –Read some input to build an item of type: a, then chop the items used to build it off the input device. Also a parse may fail so must handle failure as well.

25 Cse536 Functional Programming 25 6/24/2015 the do syntax Let x be some action with type: Action a »I.e. Action is one of IO, GUI, State, Parser etc. Then we can “extract” the object with type: a, and sequence this action with other actions by using the do syntax of haskell. do { aVal <- x ;... -- the next action ;... -- the action following } »Note that actions following aVal <- x can mention the variable aVal

26 Cse536 Functional Programming 26 6/24/2015 the return function The return function takes an object of type: a, and turns it into an action of type: Action a, which does nothing -- it “lifts” a value to an action which is a no-op do { x <-.... -- do an action which -- returns an int ; return (x + 4) -- follow it by a no-op } -- which does nothing -- and returns x+4

27 Cse536 Functional Programming 27 6/24/2015 IO actions Each function performs an action of doing some IO ? :t getChar -- get 1 char from stdin getChar :: IO Char ? :t putChar -- put Char to stdout putChar :: Char -> IO() ? :t getLine -- get a whole line from stdin getLine :: IO String ? :t readFile -- read a file into a String readFile :: FilePath -> IO String ? :t writeFile -- write a String to a file writeFile :: FilePath -> String -> IO ()

28 Cse536 Functional Programming 28 6/24/2015 A simple IO function ex2 :: IO () ex2 = do { c1 <- getChar ; c2 <- getChar -- the newline ; putChar c1 ; putChar c2 } ? ex2 -- I type this to Hugs a -- waits for input, I type: a\n a -- putChar prints a -- putChar prints the \n ?

29 Cse536 Functional Programming 29 6/24/2015 How to perform an IO action Some thing of type: IO Int is a potential action which will return an Int, if it is ever performed. In order for the action to occur, it must be performed. Any thing with type : IO a typed at top level will be performed (nothing else is ever performed). Stated another way This is the only way that an action can be performed. An actionful program builds up a potential action, which is finally performed when typed at top-level. Big actionful programs can be built by combining smaller actionful programs using do. No action is ever performed until typed at top level.

30 Cse536 Functional Programming 30 6/24/2015 Example: Combining IO actions getLine’ :: IO [Char] getLine' = do { c <- getChar -- get a char ; if c == '\n' -- if its newline then return "" -- no-op action which -- returns empty string -- recursively else do { l <- getLine' -- get a line ; return (c:l) -- no-op action } -- to cons c to l } Potentially reads a string from stdin, if it is ever performed

31 Cse536 Functional Programming 31 6/24/2015 Observations Actions are first class. –They can be abstracted (param’s of functions) –Stored in data structures. -- It is possible to have a list of actions, etc. Actions can be composed. –They can be built out of smaller actions by glueing them together with do and return –They are sequenced with do much like one uses semi-colon in languages like Pascal and C. Actions can be performed (run). –separation of construction from performance is key to their versatility. Actions of type: Action () are like statements in imperative languages. –They are used only for their side effects.

32 Cse536 Functional Programming 32 6/24/2015 Haskell separates Actions from Pure computation The unix wc (word count) program, reads a file and then prints out counts of characters, words, and lines. Reading the file is an actionfull computation, but computing the information is a pure computation. strategy –Write a function that counts the number of characters, words, and lines in a string. »Purely functional »number of lines = number of ‘\n’ »number of words ~= number of ‘ ’ plus number of ‘\t’ –Write an actionfull program that reads a file into a string and which prints out the result –combine the two.

33 Cse536 Functional Programming 33 6/24/2015 Implementation wc (cc,w,lc) [] = (cc,w,lc) wc (cc,w,lc) (' ' : xs) = wc (cc+1,w+1,lc) xs wc (cc,w,lc) ('\t' : xs) = wc (cc+1,w+1,lc) xs wc (cc,w,lc) ('\n' : xs) = wc (cc+1,w+1,lc+1) xs wc (cc,w,lc) (x : xs) = wc (cc+1,w,lc) xs ex7 = do { name <- getLine ; z <- readFile name ; let (cc,w,lc) = wc (0,0,0) z ; putStr ("The file: "++ name ++ " has \n "++(show cc)++ " characters\n "++(show w)++ " words\n "++(show lc)++ " lines\n") }

34 Cse536 Functional Programming 34 6/24/2015 Example run Hugs session for: C:\HUGS32\lib\Prelude.hs C:\HUGS32\lib\hugs\IORef.hs lect10.hs Main> ex7 lect10.hs The file: lect10.hs has 2970 characters 1249 words 141 lines Main>

35 Cse536 Functional Programming 35 6/24/2015 Interacting with the world through graphics Our first example of an action is found in chapter 3 The action is to pop up a window and to draw pictures in the window.

36 Cse536 Functional Programming 36 6/24/2015 Hello World with Graphics Lib import SOEGraphics main0 = runGraphics( do { w <- openWindow "First window" (300,300) ; drawInWindow w (text (100,200) "hello world") ; k <- getKey w ; closeWindow w } ) This imports a library, SOEGraphics, it contains many functions

37 Cse536 Functional Programming 37 6/24/2015 Graphics Operators openWindow :: String -> Point -> IO Window –opens a titled window of a particular size drawInWindow :: Window -> Draw () -> IO () –Takes a window and a Draw object and draws it –Note the return type of IO() getKey :: Window -> IO Char –Waits until any key is pressed and then returns that character closeWindow :: Window -> IO () –closes the window try it out

38 Cse536 Functional Programming 38 6/24/2015 An Action to Wait for a Space spaceClose :: Window -> IO () spaceClose w = do { k <- getKey w ; if k == ' ' then closeWindow w else spaceClose w } main1 = runGraphics( do { w <- openWindow "Second Program" (300,300) ; drawInWindow w (text (100,200) "hello Again") ; spaceClose w } )


Download ppt "Cse536 Functional Programming 1 6/24/2015 Lecture #4, Oct 6, 2004 Reading Assignments –Begin Reading chapter 3 (Simple Graphics) of the Text Homework Assignment."

Similar presentations


Ads by Google