CSc 520 Principles of Programming Languages. Currying Revisited... Currying Revisited. 16: Haskell Higher-Order Functions

Similar documents
CSc 372. Comparative Programming Languages. 11 : Haskell Higher-Order Functions. Department of Computer Science University of Arizona

CSCE 314 Programming Languages

Shell CSCE 314 TAMU. Higher Order Functions

Informatics 1 Functional Programming Lecture 7. Map, filter, fold. Don Sannella University of Edinburgh

The List Datatype. CSc 372. Comparative Programming Languages. 6 : Haskell Lists. Department of Computer Science University of Arizona

PROGRAMMING IN HASKELL. CS Chapter 6 - Recursive Functions

Watch out for the arrows. Recollecting Haskell, Part V. A start on higher types: Mapping, 1. A start on higher types: Mapping, 2.

CITS3211 FUNCTIONAL PROGRAMMING. 6. Folding operators

Lecture 10 September 11, 2017

CSc 372 Comparative Programming Languages

Standard prelude. Appendix A. A.1 Classes

Lecture 4: Higher Order Functions

Programming Languages 3. Definition and Proof by Induction

Shell CSCE 314 TAMU. Functions continued

CSCE 314 TAMU Fall CSCE 314: Programming Languages Dr. Flemming Andersen. Haskell Functions

CSc 372. Comparative Programming Languages. 8 : Haskell Function Examples. Department of Computer Science University of Arizona

CS 340 Spring 2019 Midterm Exam

CSc 372. Comparative Programming Languages. 15 : Haskell List Comprehension. Department of Computer Science University of Arizona

Haskell Refresher Informatics 2D

CS 440: Programming Languages and Translators, Spring 2019 Mon

Functional Programming Mid-term exam Tuesday 3/10/2017

A Third Look At ML. Chapter Nine Modern Programming Languages, 2nd ed. 1

Higher Order Functions in Haskell

Higher-Order Functions

Functional Programming - 2. Higher Order Functions

(ii) Define a function ulh that takes a list xs, and pairs each element with all other elements in xs.

Haskell Overview II (2A) Young Won Lim 8/23/16

Efficient Mergesort. Christian Sternagel. August 28, 2014

INTRODUCTION TO HASKELL

Haskell Overview II (2A) Young Won Lim 8/9/16

CS 457/557: Functional Languages

CSc 520. Principles of Programming Languages 11: Haskell Basics

Shell CSCE 314 TAMU. Haskell Functions

HIGHER-ORDER FUNCTIONS

Introduction to Programming: Lecture 6

Lecture 19: Functions, Types and Data Structures in Haskell

Programming Languages. Tail Recursion. CSE 130: Winter Lecture 8: NOT TR. last thing function does is a recursive call

A tour of the Haskell Prelude

CSc 372. Comparative Programming Languages. 3 : Haskell Introduction. Department of Computer Science University of Arizona

Haskell Overview II (2A) Young Won Lim 9/26/16

n n Try tutorial on front page to get started! n spring13/ n Stack Overflow!

EDAF40. 2nd June :00-19:00. WRITE ONLY ON ONE SIDE OF THE PAPER - the exams will be scanned in and only the front/ odd pages will be read.

Defining Functions. CSc 372. Comparative Programming Languages. 5 : Haskell Function Definitions. Department of Computer Science University of Arizona

Lecture 2: List algorithms using recursion and list comprehensions

PROGRAMMING IN HASKELL. Chapter 5 - List Comprehensions

CSci 4223 Principles of Programming Languages

Logic - CM0845 Introduction to Haskell

CS 320: Concepts of Programming Languages

List Functions, and Higher-Order Functions

Informatics 1 Functional Programming Lecture 4. Lists and Recursion. Don Sannella University of Edinburgh

CSE 130 [Winter 2014] Programming Languages

CSc 520. Gofer III. Accumulative Recursion. Accumulative Recursion... Stack Recursion. Principles of Programming Languages. Christian Collberg

Logical Methods in... using Haskell Getting Started

Curried and Higher Order Functions

CSc 372 Comparative Programming Languages. 4 : Haskell Basics

A general introduction to Functional Programming using Haskell

Exercise 1 ( = 24 points)

Carlos Varela RPI September 19, Adapted with permission from: Seif Haridi KTH Peter Van Roy UCL

Exercises on ML. Programming Languages. Chanseok Oh

Efficient Mergesort. Christian Sternagel. October 11, 2017

Introduction to Programming, Aug-Dec 2006

Write: evens. evens [] ====> [] evens [1;2;3;4] ====> [2;4]

COMP 3141 Software System Design and Implementation

UNIVERSITY OF EDINBURGH COLLEGE OF SCIENCE AND ENGINEERING SCHOOL OF INFORMATICS INFR08013 INFORMATICS 1 - FUNCTIONAL PROGRAMMING

Program Calculus Calculational Programming

CITS3211 FUNCTIONAL PROGRAMMING. 7. Lazy evaluation and infinite lists

Functional Programming in Haskell for A level teachers

F28PL1 Programming Languages. Lecture 14: Standard ML 4

CS115 - Module 9 - filter, map, and friends

Today s Plan. Programming Languages. Example : Factorial. Recursion. CSE 130 : Spring Lecture 6: Higher-Order Functions

Haskell: From Basic to Advanced. Part 3 A Deeper Look into Laziness

Haske k ll An introduction to Functional functional programming using Haskell Purely Lazy Example: QuickSort in Java Example: QuickSort in Haskell

Topic 5: Higher Order Functions

Topic 5: Higher Order Functions

ML Built-in Functions

An introduction introduction to functional functional programming programming using usin Haskell

CSc 372. Comparative Programming Languages. 13 : Haskell Lazy Evaluation. Department of Computer Science University of Arizona

CSc 372. Comparative Programming Languages. 4 : Haskell Basics. Department of Computer Science University of Arizona

Course year Typeclasses and their instances

CS 320 Midterm Exam. Fall 2018

Introduction to Functional Programming

UNIVERSITY OF EDINBURGH COLLEGE OF SCIENCE AND ENGINEERING SCHOOL OF INFORMATICS INFR08013 INFORMATICS 1 - FUNCTIONAL PROGRAMMING

CSCC24 Functional Programming Scheme Part 2

PROGRAMMING IN HASKELL. Chapter 2 - First Steps

CSc 520. Principles of Programming Languages 7: Scheme List Processing

CIS 194: Homework 4. Due Wednesday, February 18, What is a Number?

INTRODUCTION TO FUNCTIONAL PROGRAMMING

Functional Programming. Overview. Topics. Definition n-th Fibonacci Number. Graph

Programming Paradigms

Functional Programming TDA 452, DIT 142

Warm-up and Memoization

CSc 520 Principles of Programming Languages. Examining Lists. Constructing Lists... 7: Scheme List Processing

Recursion. Q: What does this evaluate to? Q: What does this evaluate to? CSE 130 : Programming Languages. Higher-Order Functions

Continuation Passing Style. Continuation Passing Style

Title: Recursion and Higher Order Functions

The Haskell HOP: Higher-order Programming

List Processing in Ocaml

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

General Computer Science (CH ) Fall 2016 SML Tutorial: Practice Problems

This example highlights the difference between imperative and functional programming. The imperative programming solution is based on an accumulator

Transcription:

Higher-Order Functions CSc 520 Principles of Programming Languages 16: Haskell Higher-Order Functions Christian Collberg collberg@cs.arizona.edu Department of Computer Science University of Arizona Copyright c 2004 Christian Collberg A function is Higher-Order if it takes a function as an argument or returns one as its result. Higher-order function aren t weird; the differentiation operation from high-school calculus is higher-order: deriv :: (Float->Float)->Float->Float deriv f x = (f(x+dx) - f x)/0.0001 Many recursive functions share a similar structure. We can capture such recursive patterns in a higher-order function. We can often avoid the use of explicit recursion by using higher-order functions. This leads to functions that are shorter, and easier to read and maintain. [1] 520 [2] Currying Revisited Currying Revisited... We have already seen a number of higher-order functions. In fact, any curried function is higher-order. Why? Well, when a curried function is applied to one of its arguments it returns a new function as the result. Uh, what was this currying thing? A curried function does not have to be applied to all its arguments at once. We can supply some of the arguments, thereby creating a new specialized function. This function can, for example, be passed as argument to a higher-order function. How is a curried function defined? A curried function of n arguments (of types t 1, t 2,, t n ) that returns a value of type t is defined like this: fun :: t 1 -> t 2 -> -> t n -> t This is sort of like defining n different functions (one for each ->). In fact, we could define these functions explicitly, but that would be tedious: fun 1 :: t 2 -> -> t n -> t fun 1 a 2 a n = fun 2 :: t 3 -> -> t n -> t fun 2 a 3 a n =

Currying Revisited... Currying Revisited... Duh, how about an example? Certainly. Lets define a recursive function get nth n xs which returns the n:th element from the list xs: get nth 1 (x: ) = x get nth n ( :xs) = get nth (n-1) xs get fifth "Bartholomew" h map (get nth 3) ["mob","sea","tar","bat"] "bart" So, what s the type of get second? get nth 10 "Bartholomew" e Now, let s use get nth to define functions get second, get third, get fourth, and get fifth, without using explicit recursion: get second = get nth 2 get third = get nth 3 get fourth = get nth 4 get fifth = get nth 5 [5] 520 Remember the Rule of Cancellation? The type of get nth is Int -> [a] -> a. get second applies get nth to one argument. So, to get the type of get second we need to cancel get nth s first type: Int \\\ -> [a] -> a [a] -> a. [6] Patterns of Computation Mappings Apply a function f to the elements of a list L to make a new list L. Example: Double the elements of an integer list. Selections Extract those elements from a list L that satisfy a predicate p into a new list L. Example: Extract the even elements from an integer list. Folds Combine the elements of a list L into a single element using a binary function f. Example: Sum up the elements in an integer list. The map Function map takes two arguments, a function and a list. map creates a new list by applying the function to each element of the input list. map s first argument is a function of type a -> b. The second argument is a list of type [a]. The result is a list of type [b]. map :: (a -> b) -> [a] -> [b] map f [ ] = [ ] map f (x:xs) = f x : map f xs We can check the type of an object using the :type command. Example: :type map.

The map Function... The map Function... map :: (a -> b) -> [a] -> [b] map f [ ] = [ ] map f (x:xs)= f x : map f xs inc [1,2,3,4] map :: (a -> b) -> [a] -> [b] map f [ ] = [ ] map f (x:xs) = f x : map f xs inc x = x + 1 map inc [1,2,3,4] [2,3,4,5] map [inc 1,inc 2,inc 3,inc 4 [2,3,4,5] map f [ ] = [ ] means: The result of applying the function f to the elements of an empty list is the empty list. map f (x:xs) = f x : map f xs means: applying f to the list (x:xs) is the same as applying f to x (the first element of the list), then applying f to the list xs, and then combining the results. [9] 520 [10] The map Function... The filter Function Simulation: map square [5,6] square 5 : map square [6] 25 : map square [6] 25 : (square 6 : map square [ ]) 25 : (36 : map square [ ]) 25 : (36 : [ ]) 25 : [36] [25,36] Filter takes a predicate p and a list L as arguments. It returns a list L consisting of those elements from L that satisfy p. The predicate p should have the type a -> Bool, where a is the type of the list elements. filter even [1..10] [2,4,6,8,10] filter even (map square [2..5]) filter even [4,9,16,25] [4,16] filter gt10 [2,5,9,11,23,114] where gt10 x = x > 10 [11,23,114]

The filter Function... The filter Function... We can define filter using either recursion or list comprehension. Using recursion: filter :: (a -> Bool) -> [a] -> [a] filter [] = [] filter p (x:xs) p x = x : filter p xs otherwise = filter p xs Using list comprehension: filter :: (a -> Bool) -> [a] -> [a] filter p xs = [x x <- xs, p x] filter :: (a->bool)->[a]->[a] filter [] = [] filter p (x:xs) p x = x : filter p xs otherwise = filter p xs filter even [1,2,3,4] [2,4] even [even 1, even 2, even 3, even 4] [False, True, False, True] [2,4] [1,2,3,4] f i l t e r [13] 520 [14] The filter Function... fold Functions doublepos doubles the positive integers in a list. geteven :: [Int] -> [Int] geteven xs = filter even xs doublepos :: [Int] -> [Int] doublepos xs = map dbl (filter pos xs) where dbl x = 2 * x pos x = x > 0 Simulations: geteven [1,2,3] [2] doublepos [1,2,3,4] map dbl (filter pos [1,2,3,4]) map dbl [2,4] [4,8] A common operation is to combine the elements of a list into one element. Such operations are called reductions or accumulations. sum [1,2,3,4,5] (1 + (2 + (3 + (4 + (5 + 0))))) 15 concat ["H","i","!"] ("H" ++ ("i" ++ ("!" ++ ""))) "Hi!" Notice how similar these operations are. They both combine the elements in a list using some binary operator (+, ++), starting out with a seed value (0, "").

fold Functions... fold Functions... Haskell provides a function foldr ( fold right ) which captures this pattern of computation. foldr takes three arguments: a function, a seed value, and a list. foldr (+) 0 [1,2,3,4,5] 15 foldr (++) "" ["H","i","!"] "Hi!" foldr: foldr :: (a->b->b) -> b -> [a] -> b foldr f z [ ] = z foldr f z (x:xs) = f x (foldr f z xs) Note how the fold process is started by combining the last element x n with z. Hence the name seed. foldr()z[x 1 x n ] = (x 1 (x 2 ( (x n z)))) Several functions in the standard prelude are defined using foldr: and,or :: [Bool] -> Bool and xs = foldr (&&) True xs or xs = foldr ( ) False xs? or [True,False,False] foldr ( ) False [True,False,False] True (False (False False)) True [17] 520 [18] fold Functions... fold Functions... Remember that foldr binds from the right: foldr (+) 0 [1,2,3] (1+(2+(3+0))) There is another function foldl that binds from the left: foldl (+) 0 [1,2,3] (((0+1)+2)+3) In the case of (+) and many other functions foldl()z[x 1 x n ] = foldr()z[x 1 x n ] However, one version may be more efficient than the other. In general: foldl()z[x 1 x n ] = (((z x 1 ) x 2 ) x n )

fold Functions... Operator Sections x 1 x 2 x 3 x 2 x 3 x n We ve already seen that it is possible to use operators to construct new functions: (*2) function that doubles its argument (>2) function that returns True for numbers > 2. x n z z foldr z [x 1 x n ] foldl z [x 1 x n ] x1 Such partially applied operators are know as operator sections. There are two kinds: (op a) b = b op a (*2) 4 = 4 * 2 = 8 (>2) 4 = 4 > 2 = True (++ "\n") "Bart" = "Bart" ++ "\n" [21] 520 [22] Operator Sections... takewhile & dropwhile (a op) b = a op b (3:) [1,2] = 3 : [1,2]= [3,1,2] (0<) 5 = 0 < 5 = True (1/) = 1/5 (+1) The successor function. (/2) The halving function. (:[]) The function that turns an element into a singleton list. More? filter (0<) (map (+1) [-2,-1,0,1]) [-1] We ve looked at the list-breaking functions drop & take: take 2 [ a, b, c ] [ a, b ] drop 2 [ a, b, c ] [ c ] takewhile and dropwhile are higher-order list-breaking functions. They take/drop elements from a list while a predicate is true. takewhile even [2,4,6,5,7,4,1] [2,4,6] dropwhile even [2,4,6,5,7,4,1] [5,7,4,1]

takewhile & dropwhile... takewhile & dropwhile... takewhile :: (a->bool) -> [a] -> [a] takewhile p [ ] = [ ] takewhile p (x:xs) p x = x : takewhile p xs otherwise = [ ] dropwhile :: (a->bool) -> [a] -> [a] dropwhile p [ ] = [ ] dropwhile p (x:xs) p x = dropwhile p xs otherwise = x:xs Remove initial/final blanks from a string: dropwhile ((==) ) " Hi!" "Hi!" takewhile ((/=) ) "Hi! " "Hi!" [25] 520 [26] Summary Summary... Higher-order functions take functions as arguments, or return a function as the result. We can form a new function by applying a curried function to some (but not all) of its arguments. This is called partial application. Operator sections are partially applied infix operators. The standard prelude contains many useful higher-order functions: map f xs creates a new list by applying the function f to every element of a list xs. filter p xs creates a new list by selecting only those elements from xs that satisfy the predicate p (i.e. (p x) should return True). foldr f z xs reduces a list xs down to one element, by applying the binary function f to successive elements, starting from the right. scanl/scanr f z xs perform the same functions as foldr/foldl, but instead of returning only the ultimate value they return a list of all intermediate results.

Homework Homework Homework (a): Define the map function using a list comprehension. Template: map f x = [ ] Homework (b): Use map to define a function lengthall xss which takes a list of strings xss as argument and returns a list of their lengths as result.? lengthall ["Ay", "Caramba!"] [2,8] 1. Give a accumulative recursive definition of foldl. 2. Define the minimum xs function using foldr. 3. Define a function sumsq n that returns the sum of the squares of the numbers [1 n]. Use map and foldr. 4. What does the function mystery below do? mystery xs = foldr (++) [] (map sing xs) sing x = [x] minimum [3,4,1,5,6,3] 1 [29] 520 [30] Homework... Homework Define a function zipp f xs ys that takes a function f and two lists xs=[x 1,, x n ] and ys=[y 1,, y n ] as argument, and returns the list [f x 1 y 1,, f x n y n ] as result. If the lists are of unequal length, an error should be returned. ipp (+) [1,2,3] [4,5,6] [5,7,9] ipp (==) [1,2,3] [4,2,2] [False,True,True] ipp (==) [1,2,3] [4,2] ERROR Define a function filterfirst p xs that removes the first element of xs that does not have the property p. Example: filterfirst even [2,4,6,5,6,8,7] [2,4,6,6,8,7] Use filterfirst to define a function filterlast p xs that removes the last occurence of an element of xs without the property p. Example: filterlast even [2,4,6,5,6,8,7] [2,4,6,5,6,8]