0 Odds and Ends in Haskell: Folding, I/O, and Functors Adapted from material by Miran Lipovaca.

Slides:



Advertisements
Similar presentations
15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map.
Advertisements

ML Lists.1 Standard ML Lists. ML Lists.2 Lists  A list is a finite sequence of elements. [3,5,9] ["a", "list" ] []  ML lists are immutable.  Elements.
Kathleen Fisher cs242 Reading: “A history of Haskell: Being lazy with class”,A history of Haskell: Being lazy with class Section 6.4 and Section 7 “Monads.
Functional Programming Universitatea Politehnica Bucuresti Adina Magda Florea
Chapter 3 Simple Graphics. Side Effects and Haskell  All the programs we have seen so far have no “side-effects.” That is, programs are executed only.
Advanced Programming Handout 12 Higher-Order Types (SOE Chapter 18)
Introduction to ML - Part 2 Kenny Zhu. What is next? ML has a rich set of structured values Tuples: (17, true, “stuff”) Records: {name = “george”, age.
CS510AP Quick Check Monads. QuickCheck Quick check is a Haskell library for doing random testing. You can read more about quickcheck at –
0 PROGRAMMING IN HASKELL Typeclasses and higher order functions Based on lecture notes by Graham Hutton The book “Learn You a Haskell for Great Good” (and.
Haskell Chapter 1, Part I. Highly Recommended  Learn you a Haskell for Great Good. Miran Lipovaca.
Haskell. 2 GHC and HUGS Haskell 98 is the current version of Haskell GHC (Glasgow Haskell Compiler, version 7.4.1) is the version of Haskell I am using.
Haskell Chapter 8. Input and Output  What are I/O actions?  How do I/O actions enable us to do I/O?  When are I/O actions actually performed?
Meet Perl, Part 2 Flow of Control and I/O. Perl Statements Lots of different ways to write similar statements –Can make your code look more like natural.
Chapter 9: Functional Programming in a Typed Language.
0 Functors in Haskell Adapted from material by Miran Lipovaca.
Python uses boolean variables to evaluate conditions. The boolean values True and False are returned when an expression is compared or evaluated.
16-Nov-15 More Haskell Functions Maybe, Either, List, Set, Map.
© M. Winter COSC 4P41 – Functional Programming Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.
A Third Look At ML Chapter NineModern Programming Languages, 2nd ed.1.
Lee CSCE 314 TAMU 1 CSCE 314 Programming Languages Haskell: Higher-order Functions Dr. Hyunyoung Lee.
Lee CSCE 314 TAMU 1 CSCE 314 Programming Languages Interactive Programs: I/O and Monads Dr. Hyunyoung Lee.
CMSC 330: Organization of Programming Languages Operational Semantics a.k.a. “WTF is Project 4, Part 3?”
ICS3U_FileIO.ppt File Input/Output (I/O)‏ ICS3U_FileIO.ppt File I/O Declare a file object File myFile = new File("billy.txt"); a file object whose name.
Grab Bag of Interesting Stuff. Higher Order types Type constructors are higher order since they take types as input and return types as output. Some type.
Recursion Higher Order Functions CSCE 314 Spring 2016.
Haskell Chapter 5, Part II. Topics  Review/More Higher Order Functions  Lambda functions  Folds.
24-Jun-16 Haskell Dealing with impurity. Purity Haskell is a “pure” functional programming language Functions have no side effects Input/output is a side.
0 PROGRAMMING IN HASKELL Typeclasses and higher order functions Based on lecture notes by Graham Hutton The book “Learn You a Haskell for Great Good” (and.
Polymorphic Functions
Haskell Chapter 8.
Haskell: Syntax in Functions
Recursion.
Types CSCE 314 Spring 2016.
Theory of Computation Lecture 4: Programs and Computable Functions II
PROGRAMMING IN HASKELL
More Haskell Functions
Functional Programming
More Haskell Functions
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
Chapter 4 LOOPS © Bobby Hoggard, Department of Computer Science, East Carolina University / These slides may not be used or duplicated without permission.
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
Conditions and Ifs BIS1523 – Lecture 8.
PROGRAMMING IN HASKELL
Higher Order Functions
Haskell Dealing with impurity 30-Nov-18.
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
Type & Typeclass Syntax in function
Pattern Matching Pattern matching allows us to do things like this:
Input and Output.
Higher Order Functions
Fundamentals of Functional Programming
RECURSION Haskell.
HIGHER ORDER FUNCTIONS
Haskell Dealing with impurity 8-Apr-19.
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
Programming Languages
Computer Science 312 I/O and Side Effects 1.
Theory of Computation Lecture 4: Programs and Computable Functions II
Haskell Dealing with impurity 29-May-19.
PROGRAMMING IN HASKELL
Haskell Dealing with impurity 28-Jun-19.
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
Presentation transcript:

0 Odds and Ends in Haskell: Folding, I/O, and Functors Adapted from material by Miran Lipovaca

1 The foldl function We’ve seen a particular pattern quite often with lists: - base case on empty list - some operation with the head, plus a recursive call on the tail This is such a common pattern that there is a higher-order function to handle it. Inputs: a function, a initial starting value (which we’ll call the accumulator, although it can have any name) and a list to “fold up”

2 Example: implementing the sum function sum' :: (Num a) => [a] -> a sum' xs = foldl (\acc x -> acc + x) 0 xs The binary function is applied to the accumulator and the first element (in foldl), and produces a new accumulator. Then called again with the new accumulator and the new first element of the list, until the rest of the list is empty. ghci> sum' [3,5,2,1] 11

3 In fact, we can write this function in an even shorter way, since functions can be returned as parameters: sum' :: (Num a) => [a] -> a sum' = foldl (+) 0 The lambda function on the previous slide is really the same as (+), and we can omit xs because the function written above will just return a function that takes a list as input.

4 Another example: elem Returns True if the variable is present in the list elem' :: (Eq a) => a -> [a] -> Bool elem' y ys = foldl (\acc x > if x == y then True else acc) False ys - Starting value and accumulator are booleans. - Start (and default) is False, which makes sense. - Check if current element is what we want. If so, done (so return True). Otherwise, accumulator is unchanged, and it continues on with the tail.

5 Other functions: - Foldr is the same, except starts with the end of the list (and accumulator is the second input to the function). - Scanl and scanr work just the same, but return all intermediate accumulator values in a list. - foldl1 and foldr1 work just the same as foldl and foldr, but don’t need to provide a starting value - they assume first (or last) element of the list is the starting value.

6 File I/O So far, we’ve worked mainly at the prompt, and done very little true input or output. This is logical in a functional language, since nothing has side effects! However, this is a problem with I/O, since the whole point is to take input (and hence change some value) and then output something (which requires changing the state of the screen or other I/O device. Luckily, Haskell offers work-arounds that separate the more imperative I/O.

7 A simple example: save the following file as helloword.hs main = putStrLn "hello, world" $ ghc --make helloworld [1 of 1] Compiling Main ( helloworld.hs, helloworld.o ) Linking helloworld... $./helloworld hello, world Now we actually compile a program:

8 What are these functions? ghci> :t putStrLn putStrLn :: String -> IO () ghci> :t putStrLn "hello, world" putStrLn "hello, world" :: IO () So putStrLn takes a string and returns an I/O action (which has a result type of (), the empty tuple). In Haskell, an I/O action is one with a side effect - usually either reading or printing. Usually some kind of a return value, where () is a dummy value for no return.

9 An I/O action will only be performed when you give it the name “main” and then run the program. A more interesting example: main = do putStrLn "Hello, what's your name? ” name <- getLine putStrLn ("Hey " ++ name ++ ", you rock!") Notice the do statement - more imperative style. Each step is an I/O action, and these glue together.

10 More on getLine: ghci> :t getLine getLine :: IO String This is the first I/O we’ve seen that doesn’t have an empty tuple type - it has a String. Once the string is returned, we use the <- to bind the result to the specified identifire. Notice this is the first non-functional action we’ve seen, since this function will NOT have the same value every time it is run! This is called “impure” code.

11 An invalid example: nameTag = "Hello, my name is " ++ getLine What’s the problem? Well, ++ requires both parameters to have the same type. What is the return type of getLine? Another word of warning: what does the following do? name = getLine

12 Just remember that I/O actions are only performed in a few possible places: - A main function - inside a bigger I/O block that we have composed with a do (and remember that the last action can’t be bound to a name, since that is the one that is the return type). -At the ghci prompt: ghci> putStrLn "HEEY" HEEY

13 You can use let statements inside do blocks, to call other functions (and with no “in” part required): import Data.Char main = do putStrLn "What's your first name?" firstName <- getLine putStrLn "What's your last name?" lastName <- getLine let bigFirstName = map toUpper firstName bigLastName = map toUpper lastName putStrLn $ "hey " ++ bigFirstName ++ " " ++ bigLastName ++ ", how are you?" Note that <- is for I/O, and let for expressions.

14 Return in haskell: NOT like other languages. main = do line <- getLine if null line then return () else do putStrLn $ reverseWords line main reverseWords :: String -> String reverseWords = unwords map reverse. words

15 What is return? Does NOT signal the end of execution! Return instead makes an I/O action out of a pure value. main = do a <- return "hell" b <- return "yeah!" putStrLn $ a ++ " " ++ b In essence, return is the opposite of <-. Instead of “unwrapping” I/O Strings, it wraps them.

16 Other I/O functions: -print (works on any type in show, but calls show first) -putStr - And as putStrLn, but no newline -putChar and getChar main = do print True print 2 print "haha" print 3.2 print [3,4,3] main = do c <- getChar if c /= ' ' then do putChar c main else return ()

17 More advanced functionality is available in Control.Monad: import Control.Monad import Data.Char main = forever $ do putStr "Give me some input: " l <- getLine putStrLn $ map toUpper l (Will indefinitely ask for input and print it back out capitalized.)

18 Functors Functors are a typeclass, just like Ord, Eq, Show, and all the others. This one is designed to hold things that can be mapped over; for example, lists are part of this typeclass. class Functor f where fmap :: (a -> b) -> f a -> f b This type is interesting - not like previous exmaples, like in EQ, where (==) :: (Eq a) => a -> a -> Bool. Here, f is NOT a concrete type, but a type constructor that takes one parameter.

19 Compare fmap to map: fmap :: (a -> b) -> f a -> f b map :: (a -> b) -> [a] -> [b] So map is a lot like a functor! Here, map takes a function and a list of type a, and returns a list of type b. In fact, can define map in terms of fmap: instance Functor [] where fmap = map

20 Notice what we wrote: instance Functor [] where fmap = map We did NOT write “instance Functor [a] where…”, since f has to be a type constructor that takes one type. Here, [a] is already a concrete type, while [] is a type constructor that takes one type and can produce many types, like [Int], [String], [[Int]], etc.

21 Another example: instance Functor Maybe where fmap f (Just x) = Just (f x) fmap f Nothing = Nothing Again, we did NOT write “instance Functor (Maybe m) where…”, since functor wants a type constructor. Mentally replace the f’s with Maybe, so fmap acts like (a -> b) -> Maybe a -> Maybe b. If we put (Maybe m), would have (a -> b) -> (Maybe m) a -> (Maybe m) b, which looks wrong.

22 Using it: ghci> fmap (++ " HEY GUYS IM INSIDE THE JUST") (Just "Something serious.") Just "Something serious. HEY GUYS IM INSIDE TH E JUST" ghci> fmap (++ " HEY GUYS IM INSIDE THE JUST") Nothing Nothing ghci> fmap (*2) (Just 200) Just 400 ghci> fmap (*2) Nothing Nothing