List Functions, and Higher-Order Functions

Similar documents
Option Values, Arrays, Sequences, and Lazy Evaluation

F# - LISTS. In this method, you just specify a semicolon-delimited sequence of values in square brackets. For example

02157 Functional Programming Tagged values and Higher-order list functions

02157 Functional Programming. Michael R. Ha. Tagged values and Higher-order list functions. Michael R. Hansen

Problem Solving, Programming, and Calculation

02157 Functional Programming. Michael R. Ha. Disjoint Unions and Higher-order list functions. Michael R. Hansen

Programming Languages 3. Definition and Proof by Induction

These notes are intended exclusively for the personal usage of the students of CS352 at Cal Poly Pomona. Any other usage is prohibited without

Lecture 19: Functions, Types and Data Structures in Haskell

CSE341 Section 3. Standard-Library Docs, First-Class Functions, & More

CS 320: Concepts of Programming Languages

Functional Programming and Parallel Computing

PROGRAMMING IN HASKELL. Chapter 2 - First Steps

CSE 341 Section 5. Winter 2018

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

Imperative programming in F#

Lambda Calculus and Type Inference

Introduction to Programming, Aug-Dec 2006

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

Tuples. CMSC 330: Organization of Programming Languages. Examples With Tuples. Another Example

PROGRAMMING IN HASKELL. CS Chapter 6 - Recursive Functions

CSCE 314 Programming Languages

Shell CSCE 314 TAMU. Higher Order Functions

Lab 10: OCaml sequences, comparators, stable sorting 12:00 PM, Nov 12, 2017

CSci 4223 Principles of Programming Languages

Shell CSCE 314 TAMU. Haskell Functions

CSc 372 Comparative Programming Languages

Introduction to OCaml

Solution sheet 1. Introduction. Exercise 1 - Types of values. Exercise 2 - Constructors

Programovací jazyky F# a OCaml. Chapter 5. Hiding recursion using function-as-values

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

CS 457/557: Functional Languages

CS Lecture 6: Map and Fold. Prof. Clarkson Fall Today s music: Selections from the soundtrack to 2001: A Space Odyssey

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

Haskell Introduction Lists Other Structures Data Structures. Haskell Introduction. Mark Snyder

# true;; - : bool = true. # false;; - : bool = false 9/10/ // = {s (5, "hi", 3.2), c 4, a 1, b 5} 9/10/2017 4

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

CS 321 Programming Languages

List Processing in Ocaml

CSCI-GA Scripting Languages

CS558 Programming Languages

Booleans (aka Truth Values) Programming Languages and Compilers (CS 421) Booleans and Short-Circuit Evaluation. Tuples as Values.

The Haskell HOP: Higher-order Programming

SNU Programming Language Theory

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

Lambda Calculus and Type Inference

FUNCTIONAL PROGRAMMING

L3 Programming September 19, OCaml Cheatsheet

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

PROGRAMMING IN HASKELL. Chapter 5 - List Comprehensions

CSCI-GA Final Exam

CS Lecture 6: Map and Fold. Prof. Clarkson Spring Today s music: Selections from the soundtrack to 2001: A Space Odyssey

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

An introduction introduction to functional functional programming programming using usin Haskell

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

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

CS558 Programming Languages

Functional Programming - 2. Higher Order Functions

Tail Calls. CMSC 330: Organization of Programming Languages. Tail Recursion. Tail Recursion (cont d) Names and Binding. Tail Recursion (cont d)

Why OCaml? Introduction to Objective Caml. Features of OCaml. Applications written in OCaml. Stefan Wehr

Introduction to Objective Caml

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Fall 2011

CSE341: Programming Languages Lecture 7 First-Class Functions. Dan Grossman Winter 2013

Functional Programming for Imperative Programmers

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

INTRODUCTION TO HASKELL

APCS Semester #1 Final Exam Practice Problems

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

Programming Paradigms

CPL 2016, week 10. Clojure functional core. Oleg Batrashev. April 11, Institute of Computer Science, Tartu, Estonia

Map and Fold. Prof. Clarkson Fall Today s music: Selections from the soundtrack to 2001: A Space Odyssey

Functional Programming. Lecture 2: Algebra

Shell CSCE 314 TAMU. Functions continued

CS 360: Programming Languages Lecture 10: Introduction to Haskell

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Winter 2013

CSCC24 Functional Programming Scheme Part 2

Chapter 1. Fundamentals of Higher Order Programming

Thinking Induc,vely. COS 326 David Walker Princeton University

Lecture: Functional Programming

Exercise 1: Graph coloring (10 points)

Week 5 Tutorial Structural Induction

Advanced features of Functional Programming (Haskell)

CS558 Programming Languages

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

Unit 3. Operators. School of Science and Technology INTRODUCTION

Programming Languages Fall 2013

Forward recursion. CS 321 Programming Languages. Functions calls and the stack. Functions calls and the stack

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

CSC324- TUTORIAL 5. Shems Saleh* *Some slides inspired by/based on Afsaneh Fazly s slides

CSCE 314 Programming Languages

Final Examination: Topics and Sample Problems

CompSci 220. Programming Methodology 12: Functional Data Structures

CSE399: Advanced Programming. Handout 2

Haskell Refresher Informatics 2D

Exercise 1 ( = 24 points)

The Typed Racket Guide

Haskell Scripts. Yan Huang

Functional Programming in Haskell Part I : Basics

Exercises on ML. Programming Languages. Chanseok Oh

Inductive Data Types

Transcription:

List Functions, and Higher-Order Functions Björn Lisper Dept. of Computer Science and Engineering Mälardalen University bjorn.lisper@mdh.se http://www.idt.mdh.se/ blr/ List Functions, and Higher-Order Functions (revised 2013-11-27)

List Functions We have seen some list functions already There are some important ones left We ll define List.append (@) and List.zip here List Functions, and Higher-Order Functions (revised 2013-11-27) 1

List.append (We ve seen it in use before) let rec (@) xs ys = match xs with [] -> ys x::xs -> x :: (xs @ ys) Thus, [1;2] @ [3;4;5] = 1 :: 2 :: [] @ 3 :: 4 :: 5 :: [] => 1 :: (2 :: [] @ 3 :: 4 :: 5 :: []) => 1 :: 2 :: ([] @ 3 :: 4 :: 5 :: []) => 1 :: 2 :: 3 :: 4 :: 5 :: [] = [1;2;3;4;5] Note that List.append takes time proportional to length of first argument List Functions, and Higher-Order Functions (revised 2013-11-27) 2

List.zip List.zip takes two lists and returns a list of pairs of their respective elements (like closing a zipper): zip : a list -> b list -> ( a * b) list let rec zip l1 l2 = match (l1,l2) with (x::xs,y::ys) -> (x,y) :: zip xs ys ([],[]) -> [] _ -> failwith "Lists have different length" List Functions, and Higher-Order Functions (revised 2013-11-27) 3

Thus, List.zip [1;2;3] ["allan";"tar";"kakan"] => [(1,"allan");(2,"tar");(3,"kakan")] So we can for instance use List.zip to put a number on each element in a list List.zip requires the argument lists to be of equal length Exercise: define a version that accepts lists of different length! Let the resulting list be as long as the shortest argument list List Functions, and Higher-Order Functions (revised 2013-11-27) 4

F# is a higher order language Higher-Order Functions This means that functions are data just as data of any other ordinary type They can be stored in data structures, passed as arguments, and returned as function values Functions as arguments provides a way to parameterize function definitions, where common computational structure is factored out Functions that take functions as arguments are called higher-order functions Common computational patterns can be captured as higher order functions We ll show some important examples here List Functions, and Higher-Order Functions (revised 2013-11-27) 5

Three Common Higher-Order Functions over Lists map: apply a function to all elements in a list filter: remove all elements not satisyfing a given condition fold (several versions): combine all elements using a function with two arguments (like binary operators) These functions capture common computation patterns They allow these patterns to be reused All functional languages have them Can also be defined for other data types, like arrays and trees List Functions, and Higher-Order Functions (revised 2013-11-27) 6

A First Example: List.map A common pattern is to apply a function to each element in a list An example: a function that adds one to each element in a list of integers: inclist : int list -> int list let rec inclist l = match l with [] -> [] x::xs -> x + 1 :: inclist xs inclist [2;1;3;4] => [3;2;4;5] List Functions, and Higher-Order Functions (revised 2013-11-27) 7

Computation pattern captured by a higher-order function List.map: let rec map f l = match l with [] -> [] x::xs -> f x :: map f xs List.map applies an arbitrary function f to the elements in a list List.map : ( a -> b) -> a list -> b list Note that the type of List.map is polymorphic. This is common for higher-order functions We can now define inclist through List.map instead: let inclist l = let inc n = n + 1 in map inc l List Functions, and Higher-Order Functions (revised 2013-11-27) 8

A Second Example: filter List.filter removes all elements from a list that do not satisfy a given predicate: filter : ( a -> bool) -> a list -> a list let rec filter p l = match l with [] -> [] x::xs -> if p x then x :: filter p xs else filter p xs For instance: if even returns true for exactly the even numbers, then filter even [0;1;2;3;4;5] => [0;2;4] List Functions, and Higher-Order Functions (revised 2013-11-27) 9

Some Syntax: Guarded Patterns Here is another way to define List.filter in F#: let rec filter p l = match l with [] -> [] x::xs when p x -> x :: filter p xs x::xs -> filter p xs This definition uses a guard: a condition that filters out a certain case The keyword when specifies a guard pattern when guard -> expr will return expr when the pattern is matched and the guard becomes true (Guards are just syntactic sugar) List Functions, and Higher-Order Functions (revised 2013-11-27) 10

Folds Rather than applying a function to each single member of a list, we might want to apply a function with two arguments successively to all elements An instance of this is summing all numbers in a numeric list, recall List.sum: let rec sum l = match l with [] -> 0 x::xs -> x + sum xs Applies + successively to all elements, collecting them into their sum List Functions, and Higher-Order Functions (revised 2013-11-27) 11

Now consider multiplying the numbers in a list: let rec product l = match l with [] -> 1 x::xs -> x * product xs Or, ANDing together a list of booleans: let rec all l = match l with [] -> true x::xs -> x && all xs There s something in common here! List Functions, and Higher-Order Functions (revised 2013-11-27) 12

All these functions are instances of List.foldBack: foldback : ( a -> b -> b) -> a list -> b -> b let rec foldback f l init = match l with [] -> init x::xs -> f x (foldback f xs init) We can now define: let sum xs = List.foldBack (+) xs 0 let product xs = List.foldBack (*) xs 1 let all xs = List.foldBack (&&) xs true let some xs = List.foldBack ( ) xs false Can you think of any other functions that can be defined with List.foldBack? (an example on next slide) List Functions, and Higher-Order Functions (revised 2013-11-27) 13

Remember words2string? let rec words2string ws = match ws with [] -> "" w :: rest -> w + " " + words2string rest words2string : string list -> string How define it with List.foldBack? (Solution next slide) List Functions, and Higher-Order Functions (revised 2013-11-27) 14

Define let conc_words w1 w2 = w1 + " " + w2 conc_words : string -> string -> string conc_words can now be used as a binary operator on strings Now, we can define let words2string ws = let conc_words w1 w2 = w1 + " " + w2 in List.foldBack conc_words ws "" (With nameless functions we could have avoided the explicit declaration of conc_words. More about this later) List Functions, and Higher-Order Functions (revised 2013-11-27) 15

The List module actually contains two folds: List.foldBack List.fold, defined as: fold : ( b -> a -> b) -> b -> a list -> b let rec fold f init l = match l with [] -> init x::xs -> fold f (f init x) xs List.foldBack = fold from the right List.fold = fold from the left Note the accumulating argument for List.fold, where the sum is collected List Functions, and Higher-Order Functions (revised 2013-11-27) 16

Why two Folds? Why two folds? Sometimes, one can be more efficient than the other Also, they have slightly different types, there are cases where one will work but not the other However, under some conditions they will compute the same answer (more on this later) List Functions, and Higher-Order Functions (revised 2013-11-27) 17

How do the Folds Work? Let s compare the evaluation of List.foldBack (+) [1;2;3] 0 and List.fold (+) 0 [1;2;3]: List.foldBack (+) [1;2;3] 0 => 1 + List.foldBack (+) [2;3] 0 => 1 + (2 + List.foldBack (+) [3] 0) => 1 + (2 + (3 + List.foldBack (+) [] 0)) => 1 + (2 + (3 + 0)) => 6 List.fold (+) 0 [1;2;3] => List.fold (+) (0 + 1) [2;3] => List.fold (+) ((0 + 1) + 2) [3] => List.fold (+) (((0 + 1) + 2) + 3) [] => (((0+ 1) + 2) + 3) => 6 List Functions, and Higher-Order Functions (revised 2013-11-27) 18

Note how List.fold and List.foldBack build the expression tree in different ways: fold + + 3 + 2 0 1 foldback + 1 + 2 + 3 0 Since + is associative these give the same result. The same holds for *, &&,. If the operator is not associative, then List.fold and List.foldBack can yield different results List Functions, and Higher-Order Functions (revised 2013-11-27) 19

Efficiency of List.fold vs. List.foldBack For operators on atomic types, such as + (int, float, etc.), and && (bool), List.fold is more efficient than List.foldBack Reason: since F# is call-by-value, the accumulating argument of List.fold will be evaluated for each new call Therefore, the expression tree never grows higher than one level Less stack memory is needed to hold the expression tree Also, List.fold is tail recursive: a good compiler can compile tail recursive functions into loops List Functions, and Higher-Order Functions (revised 2013-11-27) 20

Thus, sum, product, etc. are better defined as: let sum xs = List.fold (+) 0 xs let product xs = List.fold (*) 1 xs let all xs = List.fold (&&) true xs let some xs = List.fold ( ) false xs List Functions, and Higher-Order Functions (revised 2013-11-27) 21