Higher-order functions in ML

Slides:



Advertisements
Similar presentations
Higher-Order Functions and Loops c. Kathi Fisler,
Advertisements

Introduction A function is called higher-order if it takes a function as an argument or returns a function as a result. twice :: (a  a)  a  a twice.
Modern Programming Languages, 2nd ed.
ML Lists.1 Standard ML Lists. ML Lists.2 Lists A list is a finite sequence of elements. [3,5,9] ["a", "list" ] [] Elements may appear more than once [3,4]
ML Lists.1 Standard ML Lists. ML Lists.2 Lists  A list is a finite sequence of elements. [3,5,9] ["a", "list" ] []  Elements may appear more than once.
A Third Look At ML 1. Outline More pattern matching Function values and anonymous functions Higher-order functions and currying Predefined higher-order.
Introduction to OCaml Slides prepared by Matt Gruskin Some material borrowed from the CIS 500 lecture notes.
Higher-order functions in OCaml. Higher-order functions A first-order function is one whose parameters and result are all "data" A second-order function.
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists Dan Grossman Winter 2013.
F28PL1 Programming Languages Lecture 14: Standard ML 4.
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.
Cs776 (Prasad)L4Poly1 Polymorphic Type System. cs776 (Prasad)L4Poly2 Goals Allow expression of “for all types T” fun I x = x I : ’a -> ’a Allow expression.
ML Datatypes.1 Standard ML Data types. ML Datatypes.2 Concrete Datatypes  The datatype declaration creates new types  These are concrete data types,
ML Exceptions.1 Standard ML Exceptions. ML Exceptions.2 Exceptions – The Need  An extensive part of the code is error handling  A function F can return.
Getting started with ML ML is a functional programming language. ML is statically typed: The types of literals, values, expressions and functions in a.
Functional Programming. Pure Functional Programming Computation is largely performed by applying functions to values. The value of an expression depends.
CSE 341 Lecture 16 More Scheme: lists; helpers; let/let*; higher-order functions; lambdas slides created by Marty Stepp
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
Patterns in ML functions. Formal vs. actual parameters Here's a function definition (in C): –int add (int x, int y) { return x + y; } –x and y are the.
Mark Hennessy Dept. Computer Science NUI Maynooth 1 CaML continued CS 351 Programming Paradigms Dept. Computer Science NUI Maynooth.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
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.
S: Application of quicksort on an array of ints: partitioning.
Cse536 Functional Programming 1 7/14/2015 Lecture #2, Sept 29, 2004 Reading Assignments –Begin Chapter 2 of the Text Home work #1 can be found on the webpage,
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.
Functional programming Functional style makes heavy use of functions as values Hence, functional languages provide powerful constructs for manipulating.
Patterns in OCaml functions. Formal vs. actual parameters Here's a function definition (in C): –int add (int x, int y) { return x + y; } –x and y are.
Chapter 9: Functional Programming in a Typed Language.
Functional Programming With examples in F#. Pure Functional Programming Functional programming involves evaluating expressions rather than executing commands.
1-Nov-15 Haskell II Functions and patterns. Data Types Int + - * / ^ even odd Float + - * / ^ sin cos pi truncate Char ord chr isSpace isUpper … Bool.
Chapter Fifteen: Functional Programming Languages Lesson 12.
A Second Look At ML 1. Outline Patterns Local variable definitions A sorting example 2.
A Third Look At ML Chapter NineModern Programming Languages, 2nd ed.1.
Operating on Lists Chapter 6. Firsts and Seconds n Transforming list of pairs into two lists –(firsts ‘((1 5) (2 6) (3 7)))  (1 2 3) –(seconds ‘((1 5)
Introduction to Objective Caml. General comments ML is a purely functional language--there are (almost) no side effects There are two basic dialects of.
Chapter SevenModern Programming Languages1 A Second Look At ML.
Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:
0 PROGRAMMING IN HASKELL Based on lecture notes by Graham Hutton The book “Learn You a Haskell for Great Good” (and a few other sources) Odds and Ends,
Recursion Higher Order Functions CSCE 314 Spring 2016.
Haskell Chapter 5, Part II. Topics  Review/More Higher Order Functions  Lambda functions  Folds.
CSE 341 Lecture 8 curried functions Ullman 5.5 slides created by Marty Stepp
Haskell. 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.
1.SML Docs Standard Basis 2.First-Class Functions Anonymous Style Points Higher-Order 3.Examples Agenda.
6-Jul-16 Haskell II Functions and patterns. Data Types Int + - * / ^ even odd Float + - * / ^ sin cos pi truncate Char ord chr isSpace isUpper … Bool.
Recursion.
ML: a quasi-functional language with strong typing
Functions and patterns
ML Again ( Chapter 7) Patterns Local variable definitions
Haskell.
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
CMSC 330: Organization of Programming Languages
PROGRAMMING IN HASKELL
CSE 341 Lecture 3 let expressions; pattern matching Ullman
Objective caml Daniel Jackson MIT Lab for Computer Science 6898: Advanced Topics in Software Design March 18, 2002.
FP Foundations, Scheme In Text: Chapter 14.
PROGRAMMING IN HASKELL
Agenda SML Docs First-Class Functions Examples Standard Basis
Agenda SML Docs First-Class Functions Examples Standard Basis
CSCE 314: Programming Languages Dr. Dylan Shell
Higher Order Functions
CSE 341 Section 3 Nick Mooney Spring 2017.
CSE-321 Programming Languages Introduction to Functional Programming
HIGHER ORDER FUNCTIONS
CSE 3302 Programming Languages
Announcements Quiz 5 HW6 due October 23
CSE 341 Lecture 7 anonymous functions; composition of functions Ullman 5.1.3, 5.6 slides created by Marty Stepp
Functions and patterns
PROGRAMMING IN HASKELL
Functions and patterns
Presentation transcript:

Higher-order functions in ML

Higher-order functions A first-order function is one whose parameters and result are all "data" A second-order function has one or more first-order functions as parameters or result In general, a higher-order function has one or more functions as parameters or result ML supports higher-order functions

Doubling, revisited doubleAll [1,2,3,4,5]; fun doubleAll [ ] = [ ] | doubleAll (h::t) = 2 * h :: (doubleAll t); val doubleAll : int list -> int list = fn doubleAll [1,2,3,4,5]; val it : int list = [2, 4, 6, 8, 10] This is the usual heavy use of recursion It's time to simplify things

map map applies a function to every element of a list and returns a list of the results map f [x, y, z] returns [f x, f y, f z] Notice that map takes a function as an argument Ignore for now the fact that map appears to take two arguments!

Doubling list elements with map fun double x = 2 * x; fun doubleAll lst = map double lst; val doubleAll : int list -> int list = fn doubleAll [1,2,3,4,5]; val it : int list = [2, 4, 6, 8, 10] The definition of doubleAll is simpler, but... ...now we need to expose double to the world

Anonymous functions An anonymous function has the form (fn parameter => body) Now we can define doubleAll as fun doubleAll lst = map (fn x => x+x) lst; This final definition is simple and doesn't require exposing an auxiliary function

The mysterious map ML functions all take a single argument, but... map double [1,2,3] works map (double, [1,2,3]) gives a type error Even stranger, (map double) [1,2,3] works! map double; val it : int list -> int list = fn map double looks like a function...how?

Currying In ML, functions are values, and there are operations on those values Currying absorbs a parameter into a function, creating a new function map takes one argument (a function), and returns one result (also a function)

Order of operations fun add (x, y) = x + y; But also consider: val add : (int * int) -> int = fn But also consider: fun add x y = x + y; val add : int -> int -> int = fn add x y is grouped as (add x) y and int -> int -> int as int -> (int -> int)

Writing a curried function I fun add x y = x + y; val add : int -> int -> int = fn That is, add : int -> (int -> int) Our new add takes an int argument and produces an (int -> int) result (add 5) 3; (* currying happens *) val it : int = 8

Writing a curried function II MLWorks> val add5 = add 5; val add5 : int -> int = fn Notice the use of val; we are manipulating values MLWorks> add5 3; (* use our new fn *) val it : int = 8

Function composition The function composition operator is the infix lowercase letter o (f o g) x gives the same result as f(g(x)) But composition gives you a way to bundle the functions for later use; f(g(x)) requires an argument x right now val h = f o g; is perfectly legal ML

Defining higher-order functions I fun apply1(f, x) = f(x); val apply1 : (('a -> 'b) * 'a) -> 'b = fn apply1 (tl, [1,2,3]); val it : int list = [2, 3] But: apply1 tl [1,2,3]; error: Function applied to argument of wrong type

Defining higher-order functions II fun apply2 f x = f(x); val apply2 : ('a -> 'b) -> 'a -> 'b = fn apply2 tl [1,2,3]; val it : int list = [2, 3] apply2 (tl, [1,2,3]); error: Function applied to argument of wrong type Advantage: this form can be curried

A useful function: span span finds elements at the front of a list that satisfy a given predicate Example: span even [2,4,6,7,8,9,10] gives [2, 4, 6] span isn't a built-in; we have to write it

Implementing span fun span f L = if f(hd L) then (hd L) :: span f (tl L) else []; span even [2,4,6,7,8,9,10]; val it : int list = [2, 4, 6]

Extending span: span2 span returns the elements at the front of a list that satisfy a predicate Suppose we extend it to also return the remaining elements We can do it with the tools we have, but more tools would be convenient

Generalized assignment val (a, b, c) = (8, 3, 6); val a : int = 8 val b : int = 3 val c : int = 6 val x::xs = [1,2,3,4]; val x : int = 1 val xs : int list = [2, 3, 4] Generalized assignment is especially useful when a function returns a tuple

Defining local values with let let declaration ; declaration ; . . . in expression end let helps avoid redundant computations

Example of let fun circleArea (radius) = let val pi = 3.1416; fun square x = x * x in pi * square (radius) end;

Implementing span2 fun span2 f list = if f(hd list) then let val (first, second) = span2 f (tl list) in ((hd list :: first), second) end else ([], list); val span2 : ('a -> bool) -> 'a list -> ('a list * 'a list) = fn span2 even [2,4,6,7,8,9,10]; val it : (int list * int list) = ([2, 4, 6], [7, 8, 9, 10])

Another built-in function: partition Partition breaks a list into two lists: those elements that satisfy the predicate, and those that don't Example: partition even [2,4,6,7,8,9,10]; val it : (int list * int list) = ([2, 4, 6, 8, 10], [7, 9])

Quicksort Choose the first element as a pivot: For [3,1,4,1,5,9,2,6,5] choose 3 as the pivot Break the list into elements <= pivot, and elements > pivot: [1, 1, 2] and [4, 5, 9, 6, 5] Quicksort the sublists: [1, 1, 2] and [4, 5, 5, 6, 9] Append the sublists with the pivot in the middle: [1, 1, 2, 3, 4, 5, 5, 6, 9]

Quicksort in ML fun quicksort [ ] = [ ] | quicksort (x :: xs) = let val (front, back) = partition (fn n => n <= x) xs in (quicksort front) @ (x :: (quicksort back)) end; val quicksort : int list -> int list = fn quicksort [3,1,4,1,5,9,2,6,5,3,6]; val it : int list = [1, 1, 2, 3, 3, 4, 5, 5, 6, 6, ..]

foldl foldl op basis list repeatedly computes (element op basis), starting with the basis and using the list elements starting from the left foldl (op -) 10000 [1, 20, 300, 4000]; val it : int = 13719 (4000 - (300 - (20 - (1 - 10000))));

foldr foldr op basis list repeatedly computes (element op basis), starting with the basis and using the list elements starting from the right foldr (op -) 10000 [1, 20, 300, 4000]; val it : int = 6281 (1 - (20 - (300 - (4000 - 10000))));

Testing if a list is sorted The following code tests if a list is sorted: fun sorted [] = true | sorted [_] = true | sorted (x::y::rest) = x <= y andalso sorted (y::rest); This applies a (boolean) test to each adjacent pair of elements and "ANDs" the results Can we generalize this function?

Generalizing the sorted predicate fun sorted [] = true | sorted [_] = true | sorted (x::y::rest) = x <= y andalso sorted (y::rest); The underlined part is the only part specific to this particular function We can replace it with a predicate passed in as a parameter

pairwise fun pairwise f [] = true | pairwise f [_] = true | pairwise f (x::y::rest) = f(x,y) andalso pairwise f (y::rest); Here are the changes we have made: Changed the name from sorted to pairwise Added the parameter f changed x <= y to f(x, y)

Using pairwise pairwise (op <=) [1, 3, 5, 5, 9]; val it : bool = true pairwise (op <=) [1, 3, 5, 9, 5]; val it : bool = false pairwise (fn (x, y) => x = y - 1) [3,4,5,6,7]; pairwise (fn (x, y) => x = y - 1) [3,4,5,7];

The End