Introduction to SML Basic Types, Tuples, Lists, Trees and Higher-Order Functions

Similar documents
02157 Functional Programming Tagged values and Higher-order list functions

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

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

02157 Functional Programming Finite Trees (I)

02157 Functional Programming Lecture 2: Functions, Basic Types and Tuples

Introduction to SML Getting Started

ITT8060: Advanced Programming (in F#)

Lecture 2: The Basis of SML

02157 Functional Programming Lecture 1: Introduction and Getting Started

Inductive Data Types

SML A F unctional Functional Language Language Lecture 19

Processadors de Llenguatge II. Functional Paradigm. Pratt A.7 Robert Harper s SML tutorial (Sec II)

Chapter 3 Linear Structures: Lists

Higher-Order Functions

Chapter 3 Linear Structures: Lists

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

02157 Functional Programming. Michael R. Ha. Lecture 1: Introduction and Getting Started. Michael R. Hansen

A First Look at ML. Chapter Five Modern Programming Languages, 2nd ed. 1

Exercises on ML. Programming Languages. Chanseok Oh

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

02157 Functional Programming. Michael R. Ha. Finite Trees (I) Michael R. Hansen

02157 Functional Programming. Michael R. Ha. Lecture 2: Functions, Types and Lists. Michael R. Hansen

Lists. Adrian Groza. Department of Computer Science Technical University of Cluj-Napoca

Lists. Michael P. Fourman. February 2, 2010

CSci 4223 Principles of Programming Languages

Standard ML. Data types. ML Datatypes.1

Chapter 2 SML, a Functional Programming Language

2.1. Expressions. Chapter 2 SML, a Functional Programming Language. Integers. Interacting with ML

Note that pcall can be implemented using futures. That is, instead of. we can use

CS 320: Concepts of Programming Languages

List Processing in SML

Lecture 19: Functions, Types and Data Structures in Haskell

A list is a finite sequence of elements. Elements may appear more than once

A Second Look At ML. Chapter Seven Modern Programming Languages, 2nd ed. 1

PROGRAMMING IN HASKELL. Chapter 5 - List Comprehensions

CSE 341 Section 5. Winter 2018

A general introduction to Functional Programming using Haskell

Advanced features of Functional Programming (Haskell)

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

Standard prelude. Appendix A. A.1 Classes

Index. Cambridge University Press Functional Programming Using F# Michael R. Hansen and Hans Rischel. Index.

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

List Processing in SML

CS 457/557: Functional Languages

2.1. Expressions. Chapter 2 ML, a Functional Programming Language. Integers. Interacting with ML

Haskell through HUGS THE BASICS

An introduction introduction to functional functional programming programming using usin Haskell

The type checker will complain that the two branches have different types, one is string and the other is int

CSE 3302 Programming Languages Lecture 8: Functional Programming

If we have a call. Now consider fastmap, a version of map that uses futures: Now look at the call. That is, instead of

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

Lecture 4: Higher Order Functions

A Brief Introduction to Standard ML

CSc 372 Comparative Programming Languages

CSE 505. Lecture #9. October 1, Lambda Calculus. Recursion and Fixed-points. Typed Lambda Calculi. Least Fixed Point

Functional Programming - 2. Higher Order Functions

Lecture 2: List algorithms using recursion and list comprehensions

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

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

Mini-ML. CS 502 Lecture 2 8/28/08

F28PL1 Programming Languages. Lecture 11: Standard ML 1

CSE341 Autumn 2017, Midterm Examination October 30, 2017

Introduction to Programming, Aug-Dec 2006

Overloading, Type Classes, and Algebraic Datatypes

CSE341, Fall 2011, Midterm Examination October 31, 2011

Functional Programming

Datatype declarations

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

Haskell 5.1 INTERACTIVE SESSIONS AND THE RUN-TIME SYSTEM

02157 Functional Programming Lecture 3: Lists

Programming Paradigms Languages F28PL, Lecture 1

Data types for mcrl2

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

CS109A ML Notes for the Week of 1/16/96. Using ML. ML can be used as an interactive language. We. shall use a version running under UNIX, called

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

Topic 7: Algebraic Data Types

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

F28PL1 Programming Languages. Lecture 14: Standard ML 4

Handout 2 August 25, 2008

Shell CSCE 314 TAMU. Higher Order Functions

CSE-321 Programming Languages 2012 Midterm

Products and Records

Algebraic Types. Chapter 14 of Thompson

A Fourth Look At ML. Chapter Eleven Modern Programming Languages, 2nd ed. 1

Redefinition of an identifier is OK, but this is redefinition not assignment; Thus

Higher Order Functions in Haskell

Logic - CM0845 Introduction to Haskell

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

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

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

Functional Programming in Haskell Part I : Basics

CSE3322 Programming Languages and Implementation

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

CS 440: Programming Languages and Translators, Spring 2019 Mon

CS 321 Programming Languages

Functors signature Order = sig functor name type elem (structname:signature) = structure definition; val le : elem*elem -> bool end; elem

CSE341, Fall 2011, Midterm Examination October 31, 2011

Programming Languages 3. Definition and Proof by Induction

Specification and Verification in Higher Order Logic

Shell CSCE 314 TAMU. Functions continued

Transcription:

Introduction to SML Basic Types, Tuples, Lists, Trees and Higher-Order Functions Michael R. Hansen mrh@imm.dtu.dk Informatics and Mathematical Modelling Technical University of Denmark c Michael R. Hansen, Spring 2005 p.1/59

Basic Types: Integers A data type comprises a set of values and a collection of operations c Michael R. Hansen, Spring 2005 p.2/59

Basic Types: Integers A data type comprises a set of values and a collection of operations Integers Type name : int Values : 27, 0, 1024 Operations: (A few selected) Operator Type Precedence Association int -> int Highest * div mod int * int -> int 7 Left + - int * int -> int 6 Left = <> < <= int * int -> bool 4 Left See also the library Int c Michael R. Hansen, Spring 2005 p.2/59

Reals Type name : real Values : 27.0, 0.0, 1024.71717, 23.4E 11 Operations: (A few selected) Operator Type Precedence Association abs real -> real Highest * / real*real -> real 7 Left + - real*real -> real 6 Left = <> < <= real*real -> bool 4 Left See also the libraries Real and Math c Michael R. Hansen, Spring 2005 p.3/59

Reals Type name : real Values : 27.0, 0.0, 1024.71717, 23.4E 11 Operations: (A few selected) Operator Type Precedence Association abs real -> real Highest * / real*real -> real 7 Left + - real*real -> real 6 Left = <> < <= real*real -> bool 4 Left See also the libraries Real and Math Some built-in operators are overloaded. *: Default is int real*real -> real int * int -> int c Michael R. Hansen, Spring 2005 p.3/59

Overloaded Operators and Type inference A squaring function on integers: Declaration Type fun square x = x * x int -> int Default c Michael R. Hansen, Spring 2005 p.4/59

Overloaded Operators and Type inference A squaring function on integers: Declaration Type fun square x = x * x int -> int Default A squaring function on reals: square: real -> real Declaration c Michael R. Hansen, Spring 2005 p.4/59

Overloaded Operators and Type inference A squaring function on integers: Declaration Type fun square x = x * x int -> int Default A squaring function on reals: square: Declaration fun square(x:real) = x * x real -> real Type the argument c Michael R. Hansen, Spring 2005 p.4/59

Overloaded Operators and Type inference A squaring function on integers: Declaration Type fun square x = x * x int -> int Default A squaring function on reals: square: real -> real Declaration fun square x:real = x * x Type the result c Michael R. Hansen, Spring 2005 p.4/59

Overloaded Operators and Type inference A squaring function on integers: Declaration Type fun square x = x * x int -> int Default A squaring function on reals: square: real -> real Declaration fun square x = x * x: real Type expression for the result c Michael R. Hansen, Spring 2005 p.4/59

Overloaded Operators and Type inference A squaring function on integers: Declaration Type fun square x = x * x int -> int Default A squaring function on reals: square: real -> real Declaration fun square x = x:real * x Type a variable c Michael R. Hansen, Spring 2005 p.4/59

Overloaded Operators and Type inference A squaring function on integers: Declaration Type fun square x = x * x int -> int Default A squaring function on reals: square: real -> real Declaration fun square x = x:real * x Type a variable Choose any mixture of these possibilities c Michael R. Hansen, Spring 2005 p.4/59

Characters Type name char Values #"a", #" ", #"\"" (escape sequence for ") Operator Type ord char -> int ascii code of character chr int -> char character for ascii code = < <=... char*char -> bool comparisons by ascii codes Examples - ord #"a"; > val it = 97 : int - ord #"A"; > val it = 65 : int - #"a" < #"A"; > val it = false : bool; - chr 88; > val it = #"X" : char c Michael R. Hansen, Spring 2005 p.5/59

Strings Type name string Values "abcd", " ", "", "123\"321" (escape sequence for ") Operator Type size string -> int length of string ˆ string*string -> string concatenation = < <=... string*string -> bool comparisons Int.toString int -> string conversions Examples - "auto" < "car"; > val it = true : bool - "abc"ˆ"de"; > val it = "abcde": string - size("abc"ˆ"def"); > val it = 6 : int - Int.toString(6+18); > val it = "24" : string c Michael R. Hansen, Spring 2005 p.6/59

Booleans Type name bool Values false, true Operator Type not bool -> bool negation not true = false not false = true Expressions e 1 andalso e 2 conjunction e 1 e 2 e 1 orelse e 2 disjunction e 1 e 2 are lazily evaluated, e.g. 1<2 orelse 5/0 = 1 true Precedence: andalse has higher than orelse c Michael R. Hansen, Spring 2005 p.7/59

Tuples An ordered collection of n values (v 1, v 2,..., v n ) is called an n-tuple Examples - (); > val it = () : unit - (3, false); > val it = (3, false) : int * bool - (1, 2, ("ab",true)); > val it = (1, 2, ("ab", true)) :? 0-tuple 2-tuples (pairs) 3-tuples (triples) Selection Operation: #i(v 1, v 2,..., v n ) = v i. #2(1,2,3) = 2 Equality defined componentwise - (1, 2.0, true) = (2-1, 2.0*1.0, 1<2); > val it = true : bool provided = is defined on components c Michael R. Hansen, Spring 2005 p.8/59

Tuple patterns Extract components of tuples - val ((x,_),(_,y,_)) = ((1,true),("a","b",false)); > val x = 1 : int val y = "b" : string Pattern matching yields bindings Restriction - val (x,x) = (1,1);! Toplevel input:! val (x,x) = (1,1);! ˆ! identifier is bound twice in a pattern c Michael R. Hansen, Spring 2005 p.9/59

Infix functions Directives: infix d f and infixr d f. d is the precedence of f Example: exclusive-or infix 0 xor (* or just infix xor -- lowest precedence *) fun false xor true = true true xor false = true _ xor _ = false type? - 1 < 2+3 xor 2.0 / 3.0 > 1.0; > val it = true : bool Infix status can be removed by nonfix xor - xor(1 < 2+3, 2.0 / 3.0 > 1.0); > val it = true : bool c Michael R. Hansen, Spring 2005 p.10/59

Let expressions let dec in e end Bindings obtained from dec are valid only in e Example: Solve ax 2 + bx + c = 0 type equation = real * real * real type solution = real * real exception Solve; (* declares an exception *) fun solve(a,b,c) = let val d = b*b-4.0*a*c in if d < 0.0 orelse a = 0.0 then raise Solve else (( b+math.sqrt d)/(2.0*a),( b-math.sqrt d)/(2.0*a)) end; The type of solve is equation -> solution d is declared once and used 3 times readability, efficiency c Michael R. Hansen, Spring 2005 p.11/59

Local declarations local dec 2 in dec 2 end Bindings obtained from dec 1 are valid only in dec 2 local fun disc(a,b,c) = b*b - 4.0*a*c in exception Solve; fun hastwosolutions(a,b,c) = disc(a,b,c)>0.0 andalso a<>0.0; fun solve(a,b,c) = let val d = disc(a,b,c) in if d < 0.0 orelse a = 0.0 then raise Solve else (( b+math.sqrt d)/(2.0*a),( b-math.sqrt d)/(2.0*a)) end end; c Michael R. Hansen, Spring 2005 p.12/59

Lists: Overview values and constructors recursions following the structure of lists useful built-in functions polymorphic types, values and functions c Michael R. Hansen, Spring 2005 p.13/59

Lists A list is a finite sequence of elements having the same type: [v 1,..., v n ] ([ ] is called the empty list) c Michael R. Hansen, Spring 2005 p.14/59

Lists A list is a finite sequence of elements having the same type: [v 1,..., v n ] ([ ] is called the empty list) - [2,3,6]; > val it = [2, 3, 6] : int list c Michael R. Hansen, Spring 2005 p.14/59

Lists A list is a finite sequence of elements having the same type: [v 1,..., v n ] ([ ] is called the empty list) - ["a", "ab", "abc", ""]; > val it = ["a", "ab", "abc", ""] : string list c Michael R. Hansen, Spring 2005 p.14/59

Lists A list is a finite sequence of elements having the same type: [v 1,..., v n ] ([ ] is called the empty list) - [Math.sin, Math.cos]; > val it = [fn, fn] : (real -> real) list c Michael R. Hansen, Spring 2005 p.14/59

Lists A list is a finite sequence of elements having the same type: [v 1,..., v n ] ([ ] is called the empty list) - [(1,true), (3,true)]; > val it = [(1, true),(3, true)]: (int*bool) list c Michael R. Hansen, Spring 2005 p.14/59

Lists A list is a finite sequence of elements having the same type: [v 1,..., v n ] ([ ] is called the empty list) - [[],[1],[1,2]]; > val it = [[], [1], [1, 2]] : int list list c Michael R. Hansen, Spring 2005 p.14/59

The type constructor: list If τ is a type, so is τ list Examples: int list (string * int) list ((int -> string) list ) list list has higher precedence than * and -> int * real list -> bool list means (int * (real list)) -> (bool list) c Michael R. Hansen, Spring 2005 p.15/59

Trees for lists A non-empty list [x 1, x 2,..., x n ], n 1, consists of a head x 1 and a tail [x 2,..., x n ] c Michael R. Hansen, Spring 2005 p.16/59

Trees for lists A non-empty list [x 1, x 2,..., x n ], n 1, consists of a head x 1 and a tail [x 2,..., x n ] :: 2 :: 3 :: 2 nil Graph for [2,3,2] :: 2 nil Graph for [2] c Michael R. Hansen, Spring 2005 p.16/59

List constructors: [], nil and :: Lists are generated as follows: the empty list is a list, designated [] or nil if x is an element and xs is a list, then so is x :: xs (type consistency) :: associate to the right, i.e. x 1 ::x 2 ::xs c Michael R. Hansen, Spring 2005 p.17/59

List constructors: [], nil and :: Lists are generated as follows: the empty list is a list, designated [] or nil if x is an element and xs is a list, then so is x :: xs (type consistency) :: associate to the right, i.e. x 1 ::x 2 ::xs means x 1 ::(x 2 ::xs) c Michael R. Hansen, Spring 2005 p.17/59

List constructors: [], nil and :: Lists are generated as follows: the empty list is a list, designated [] or nil if x is an element and xs is a list, then so is x :: xs (type consistency) :: associate to the right, i.e. x 1 ::x 2 ::xs means x 1 ::(x 2 ::xs) :: x 1 :: x 2 xs Graph for x 1 ::x 2 ::xs c Michael R. Hansen, Spring 2005 p.17/59

Recursion on lists a simple example n suml [x 1,x 2,...,x n ] = x i = x 1 + x 2 + + x n = x 1 + i=1 n i=2 x i Constructors are used in list patterns fun suml [] = 0 suml( x::xs) = x + suml xs > val suml = fn : int list -> int suml [1,2] 1 + suml [2] (x 1 and xs [2]) 1 + (2 + suml []) (x 2 and xs []) 1 + (2 + 0) (the pattern [] matches the value []) 1 + 2 3 Recursion follows the structure of lists c Michael R. Hansen, Spring 2005 p.18/59

Append The infix operator @ (called append ) joins two lists: Properties [x 1,x 2,...,x m ] @ [y 1,y 2,...,y n ] = [x 1,x 2,...,x m,y 1,y 2,...,y n ] [] @ ys = ys [x 1,x 2,...,x m ] @ ys = x 1 ::([x 2,...,x m ] @ ys) Declaration infixr 5 @ (* right associative fun [] @ ys = ys (x::xs) @ ys = x::(xs @ ys); c Michael R. Hansen, Spring 2005 p.19/59

Append: evaluation infixr 5 @ (* right associative *) fun [] @ ys = ys (x::xs) @ ys = x::(xs @ ys); Evaluation [1,2] @ [3,4] 1::([2] @ [3,4]) (x 1, xs [2], ys [3, 4]) 1::(2::([] @ [3,4])) (x 2, xs [ ], ys [3, 4]) 1::(2::[3,4]) (ys [3, 4]) 1::[2,3,4] [1,2,3,4] c Michael R. Hansen, Spring 2005 p.20/59

Append: polymorphic type > infixr 5 @ > val @ = fn : a list * a list -> a list a is a type variable The type of @ is polymorphic it has many forms a = int: Appending integer lists [1,2] @ [3,4]; val it = [1,2,3,4] : int list a = int list: Appending lists of integer list [[1],[2,3]] @ [[4]]; val it = [[1],[2,3],[4]] : int list list @ is a built-in function c Michael R. Hansen, Spring 2005 p.21/59

Reverse rev [x 1, x 2,..., x n ] = [x n,..., x 2, x 1 ] fun naive_rev [] = [] naive_rev(x::xs) = naive_rev xs @ [x]; val naive_rev = fn : a list -> a list naive_rev[1,2,3] naive_rev[2,3] @ [1] (naive_rev[3] @ [2]) @ [1] ((naive_rev[] @ [3]) @ [2]) @ [1] (([] @ [3]) @ [2]) @ [1] ([3] @ [2]) @ [1] (3::([] @ [2])) @ [1] [3,2,1] efficient version is built-in (see Ch. 17) c Michael R. Hansen, Spring 2005 p.22/59

Membership equality types Declaration infix member x member [y 1,y 2,...,y n ] = (x = y 1 ) (x = y 2 ) (x = y n ) = (x = y 1 ) (x member [y 2,...,y n ]) fun x member [] = false x member (y::ys) = x=y orelse x member ys; infix 0 member val member = fn : a * a list -> bool a is an equality type variable no functions (1,true) member [(2,true), (1,false)] false [1,2,3] member [[1], [], [1,2,3]]? c Michael R. Hansen, Spring 2005 p.23/59

Value polymorphism e is a value expression if no further evaluation is needed - (5,[]); (* val it = (5,[]); *) > val a it = (5, []) : int * a list - rev []; (* non-value expression *)! Warning: Value polymorphism:! Free type variable(s) at top level in value id. it A type is monomorphic is it contains no type variables, otherwise it is polymorphic SML resticts the use of polymorphic types as follows: see Ch. 18 all monomorphic expressions are OK all value expressions are OK at top-level, polymorphic non-value expressions are forbidden c Michael R. Hansen, Spring 2005 p.24/59

Examples remove(x, ys) : removes all occurrences of x in the list ys prefix(xs, ys) : the list xs is a prefix of the list ys (ex. 5.10) sum(p, xs) : the sum of all elements in xs satisfying the predicate p: int -> bool (ex. 5.15) From list of pairs to pair of lists: unzip [(x 1, y 1 ), (x 2, y 2 ),..., (x n, y n )] = ([x 1, x 2,..., x n ], [y 1 y 2,..., y n ]) Many functions on lists are predefined, e.g. @, rev, length, and also the SML basis library contains functions on lists, e.g. unzip. See for example List, ListPair c Michael R. Hansen, Spring 2005 p.25/59

Overview Disjoint Sets The datatype simple version case expressions c Michael R. Hansen, Spring 2005 p.26/59

Disjoint Sets: An Example A shape is either a circle, a square, or a triangle the union of three disjoint sets A datatype declaration for shapes: datatype shape = Circle of real Square of real Triangle of real*real*real; Answer from the SML system: > datatype shape > con Circle = fn : real -> shape > con Square = fn : real -> shape > con Triangle = fn : real * real * real -> shape c Michael R. Hansen, Spring 2005 p.27/59

Constructors of a datatype The tags Circle, Square and Triangle are constructors of values of type shape - Circle 2.0; > val it = Circle 2.0 : shape - Triangle(1.0, 2.0, 3.0); > val it = Triangle(1.0, 2.0, 3.0) : shape - Square 4.0; > val it = Square 4.0 : shape Equality on shapes is defined provided... - Triangle(1.0, 2.0, 3.0) = Square 2.0; > val it = false : bool c Michael R. Hansen, Spring 2005 p.28/59

Constructors in Patterns fun area(circle r) = Math.pi * r * r area(square a) = a * a area(triangle(a,b,c)) = let val d = (a + b + c)/2.0 in Math.sqrt(d*(d-a)*(d-b)*(d-c)) end; > val area = fn : shape -> real a constructor only matches itself area (Circle 1.2) (Math.pi * r * r, [r 1.2])... c Michael R. Hansen, Spring 2005 p.29/59

The case-expression Form: case exp of pat 1 => e 1 pat 2 => e 2... pat k => e k Example: fun area s = case s of (Circle r) => Math.pi * r * r (Square a) => a*a (Triangle(a,b,c)) => let val d = (a + b + c)/2.0 in Math.sqrt(d*(d-a)*(d-b)*(d-c)) end; c Michael R. Hansen, Spring 2005 p.30/59

Enumeration types the order type datatype order = LESS EQUAL GREATER; Predefined compare functions, e.g. LESS if x < y Int.compare(x, y) = EQUAL if x = y GREATER if x > y Example: fun countleg [] = (0,0,0) countleg(x::rest) = let val (y1,y2,y3) = countleg rest in case Int.compare(x,0) of LESS => (y1+1,y2,y3 ) EQUAL => (y1,y2+1,y3 ) GREATER => (y1,y2,y3+1) end; c Michael R. Hansen, Spring 2005 p.31/59

The option type datatype a option = NONE SOME of a; Example fun smallest [] = NONE smallest(x::xs) = case smallest xs of NONE => SOME x SOME y => if x< y then SOME x else SOME y; > val smallest = fn : int list -> int option - smallest [2, 3, 6]; > val it = SOME 3 : int option c Michael R. Hansen, Spring 2005 p.32/59

smallest continued The predefined function valof: exception Option; fun valof(some x) = x valof NONE = raise Option; > val a valof = fn : a option -> a - 3 + valof(smallest [1,2,9]); > val it = 4 : int c Michael R. Hansen, Spring 2005 p.33/59

Overview Finite Trees Algebraic Datatypes. Recursions following the structure of trees. c Michael R. Hansen, Spring 2005 p.34/59

Trees A finite tree is a value which may contain a subcomponent of the same type. Example: A binary search tree Br Br Br Br 7 Lf Br 21 Br Lf 2 Lf 9 Lf 13 Lf Lf 25 Lf Condition: for every node containing the value x: every value in the left subtree is smaller then x, and every value in the right subtree is greater than x. c Michael R. Hansen, Spring 2005 p.35/59

Binary Trees A recursive datatype is used to represent values with are trees. datatype tree = Lf Br of tree*int*tree; > datatype tree > con Lf = Lf : tree > con Br = fn : tree * int * tree -> tree c Michael R. Hansen, Spring 2005 p.36/59

Binary Trees A recursive datatype is used to represent values with are trees. datatype tree = Lf Br of tree*int*tree; > datatype tree > con Lf = Lf : tree > con Br = fn : tree * int * tree -> tree The two parts in the declaration are rules for generating trees: Lf is a tree if t 1, t 2 are trees, n is an integer, then Br(t 1, n, t 2 ) is a tree. c Michael R. Hansen, Spring 2005 p.36/59

Binary Trees A recursive datatype is used to represent values with are trees. datatype tree = Lf Br of tree*int*tree; > datatype tree > con Lf = Lf : tree > con Br = fn : tree * int * tree -> tree The two parts in the declaration are rules for generating trees: Lf is a tree if t 1, t 2 are trees, n is an integer, then Br(t 1, n, t 2 ) is a tree. The tree from the previous slide is denoted by: Br(Br(Br(Lf,2,Lf),7,Lf), 9, Br(Br(Lf,13,Lf),21,Br(Lf,25,Lf))) c Michael R. Hansen, Spring 2005 p.36/59

Binary search trees: Insertion Recursion on the structure of trees: Constructors Lf and Br are used in patterns fun insert(i, Lf) = Br(Lf,i,Lf) insert(i, tr as Br(t1,j,t2)) = case Int.compare(i,j) of EQUAL => tr LESS => Br(insert(i,t1),j,t2) GREATER => Br(t1,j,insert(i,t2)) The search tree condition is an invariant for insert Example: - val t1 = Br(Lf, 3, Br(Lf, 5, Lf)); - val t2 = insert(4, t1); > val t2 = Br(Lf, 3, Br(Br(Lf, 4, Lf), 5, Lf)) : tree c Michael R. Hansen, Spring 2005 p.37/59

Binary search trees: member and tolist fun member(i, Lf) = false member(i, Br(t1,j,t2)) = case Int.compare(i,j) of EQUAL => true LESS => member(i,t1) GREATER => member(i,t2) > val member = fn : int * tree -> bool In-order traversal fun tolist Lf = [] tolist(br(t1,j,t2)) = tolist t1 @ [j] @ tolist t2; > val tolist = fn : tree -> int list gives a sorted list - tolist(br(br(lf,1,lf), 3, Br(Br(Lf,4,Lf), 5, Lf))); > val it = [1, 3, 4, 5] : int list c Michael R. Hansen, Spring 2005 p.38/59

Deletions in search trees Delete minimal element in a search tree: tree -> int * tree fun delmin(br(lf,i,t2)) = (i,t2) delmin(br(t1,i,t2)) = let val (m,t1 ) = delmin t1 in (m, Br(t1,i,t2)) end Delete element in a search tree: tree * int -> tree fun delete(lf,_) = Lf delete(br(t1,i,t2),j) = case Int.compare(i,j) of LESS => Br(t1,i,delete(t2,j)) GREATER => Br(delete(t1,j),i,t2) EQUAL => (case (t1,t2) of (Lf,_) => t2 (_,Lf) => t1 _ => let val (m,t2 ) = delmin t2 in Br(t1,m,t2 ) end) c Michael R. Hansen, Spring 2005 p.39/59

Expression Trees infix 6 ++ --; infix 7 ** //; datatype fexpr = Const of real X ++ of fexpr * fexpr -- of fexpr * fexpr ** of fexpr * fexpr // of fexpr * fexpr > datatype fexpr con ** : fexpr * fexpr -> fexpr con ++ : fexpr * fexpr -> fexpr con -- : fexpr * fexpr -> fexpr con // : fexpr * fexpr -> fexpr con X : fexpr con Const : real -> fexpr c Michael R. Hansen, Spring 2005 p.40/59

Expressions: Computation of values comp : fexpr * real -> real fun comp(const r,_) = r comp(x,y) = y comp(fe1 ++ fe2,y) = comp(fe1,y) + comp(fe2,y) comp(fe1 -- fe2,y) = comp(fe1,y) - comp(fe2,y) comp(fe1 ** fe2,y) = comp(fe1,y) * comp(fe2,y) comp(fe1 // fe2,y) = comp(fe1,y) / comp(fe2,y) Example: comp(x ** (Const 2.0 ++ X), 4.0); > val it = 24.0 : real c Michael R. Hansen, Spring 2005 p.41/59

Overview Contents Higher-order functions Anonymous functions Higher-order list functions (in the library) map exists, all, filter foldl, foldr Many recursive declarations follows the same schema. Succinct declarations using higher-order functions. Parameterization of program modules c Michael R. Hansen, Spring 2005 p.42/59

Higher-order functions A function f : τ 1 τ 2 is a higher-order function, if a function type τ τ occurs in either τ 1 or τ 2 or both. Functions are first class citizens c Michael R. Hansen, Spring 2005 p.43/59

Higher-order functions A function f : τ 1 τ 2 is a higher-order function, if a function type τ τ occurs in either τ 1 or τ 2 or both. fun f x = let fun g y = x+y in g end; > val f = fn : int -> int -> int - f 2; > val it = fn : int -> int - it 3; > val it = 5 : int Functions are first class citizens c Michael R. Hansen, Spring 2005 p.43/59

Anonymous functions Expressions denoting functions can be written using fn expressions: fn pat 1 => e 1 pat 2 => e 2 pat n => e n Yields the value obtained by evaluation of the expression: let fun f x = case x of pat 1 => e 1 pat 2 => e 2 pat n => e n in f end Examples: fn n => 2 * n; fn 0 => false _ => true; fn r => Math.pi * r * r; c Michael R. Hansen, Spring 2005 p.44/59

Declarations having the same structure fun poslist [] = [] poslist (x::xs) = (x > 0)::posList xs; val poslist = fn : int list -> bool list poslist [4, 5, 6]; > val it = [true,false,true] : bool list Applies the function fn x => x > 0 to each element in a list fun addelems [] = [] addelems ((x,y)::zs) = (x + y)::addelems zs; > val addelems = fn : (int * int) list -> int list addelems [(1,2),(3,4)]; > val it = [3, 7] : int list Applies the sum function op+ to each pair of integers in a list c Michael R. Hansen, Spring 2005 p.45/59

The function: map Applies a function to each element in a list map f [v 1, v 2,..., v n ] = [f(v 1 ), f(v 2 ),..., f(v n )] Declaration Library function fun map f = fn [] => [] (x::xs) => f x :: map f xs; > val map = fn : ( a -> b) -> a list -> b list Succinct declarations can be achieved using map, e.g. val poslist = map (fn x => x > 0); > val poslist = fn : int list -> bool list val addelems = map op+ - val addelems = fn : (int * int) list -> int list c Michael R. Hansen, Spring 2005 p.46/59

Declaration of higher-order functions Commonly used form fun map f [] = [] map f (x::xs) = f x :: map f xs; > val map = fn : ( a -> b) -> a list -> b list General form fun f pat 11 pat 12... pat 1n = e 1 f pat 21 pat 22... pat 2n = e 2... f pat k1 pat k2... pat kn = e k c Michael R. Hansen, Spring 2005 p.47/59

Exercise Declare a function g [x 1,..., x n ] = [x 2 1 + 1,..., x 2 n + 1] Remember map f [v 1, v 2,..., v n ] = [f(v 1 ), f(v 2 ),..., f(v n )] c Michael R. Hansen, Spring 2005 p.48/59

Higher-order list functions: exists exists p xs = { true false if p(x) = true for some x in xs otherwise Declaration Library function fun exists p [] = false exists p (x::xs) = p x orelse exists p xs; > val exists = fn: ( a -> bool) -> a list -> bool Example exists (fn x => x>=2) [1,3,1,4]; > val it = true : bool c Michael R. Hansen, Spring 2005 p.49/59

Exercise Declare member function using exists. infix member; fun x member ys = exists????? ; > val member = fn : a * a list -> bool Remember exists p xs = { true false if p(x) = true for some x in xs otherwise c Michael R. Hansen, Spring 2005 p.50/59

Higher-order list functions: all { all p xs = true false if p(x) = true, for all elements x in xs otherwise Declaration Library function fun all p [] = true all p (x::xs) = p x andalso all p xs; > val all = fn: ( a -> bool) -> a list -> bool Example all (fn x => x>=2) [1,3,1,4]; > val it = false : bool c Michael R. Hansen, Spring 2005 p.51/59

Exercise Declare a function subset(xs, ys) which is true when every element in the lists xs is in ys, and false otherwise. Remember all p xs = { true false if p(x) = true, for all elements x in xs otherwise c Michael R. Hansen, Spring 2005 p.52/59

Higher-order list functions: filter filter p xs is the list of those elements x of xs where p(x) = true. Declaration Library function fun filter p [] = [] filter p (x::xs) = if p x then x :: filter p xs else filter p xs; > val filter = fn: ( a -> bool) -> a list -> a list Example filter Char.isAlpha [#"1", #"p", #"F", #"-"]; > val it = [#"p", #"F"] : char list where Char.isAlpha c is true iff c {#"A",..., #"Z"} {#"a",..., #"z"} c Michael R. Hansen, Spring 2005 p.53/59

Exercise Declare a function inter(xs, ys) which contains the common elements of the lists xs and ys i.e. their intersection. Remember filter p xs is the list of those elements x of xs where p(x) = true. c Michael R. Hansen, Spring 2005 p.54/59

Higher-order list functions: foldr (1) foldr accumulates a function f from a start value b over the elements of a list [x 1, x 2,..., x n ] (from right to left): foldr f b [x 1, x 2,..., x n 1, x n ] = f(x 1, f(x 2,..., f(x n 1, f(x n, b)) )) }{{} foldr f b [x 2,...,x n 1,x n ] Declaration Library function fun foldr f b [] = b foldr f b (x::xs) = f(x,foldr f b xs); > val foldr = fn : ( a * b -> b) -> b -> a list -> b Example: the lenght function fun length xs = foldr (fn (_,y) => y+1) 0 xs; > val length = fn : a list -> int length [4,5,6]; > val it = 3 : int c Michael R. Hansen, Spring 2005 p.55/59

Higher-order list functions: foldr (2) Accumulation of an infix operator. Evaluation is as follows foldr op b [x 1,x 2,...,x n ] x 1 (x 2 (x n b) ) Examples: Addition and Append fun sumr xs = foldr op+ 0 xs; > val sumr = fn : int list -> int sumr [1,2,3,4]; > val it = 10 : int fun append(xs,ys) = foldr op:: ys xs; > val append = fn : a list * a list -> a list append([1,2,3],[4,5]); > val it = [1,2,3,4,5] : int list c Michael R. Hansen, Spring 2005 p.56/59

Exercise: union of sets Let an insertion function be declared by fun insert(x, ys) = if x member ys then ys else x::ys Declare a union function on sets. Remember: foldr op b [x 1,x 2,...,x n ] x 1 (x 2 (x n b) ) c Michael R. Hansen, Spring 2005 p.57/59

Higher-order list functions: foldl (1) foldl accumulates a function f from a start value b over the elements of a list [x 1, x 2,..., x n ] (from left to right): b {}} { foldl f b [x 1,x 2,...,x n 1,x n ] = f(x n, f(x n 1,..., f(x 2, f(x 1, b)) )) }{{} foldl f b [x 2,...,x n 1,x n ] Declaration Library function fun foldl f b [] = b foldl f b (x::xs) = foldl f (f(x,b)) xs; > val foldl = fn : ( a * b -> b) -> b -> a list -> b c Michael R. Hansen, Spring 2005 p.58/59

Higher-order list functions: foldl (2) Accumulation of an infix operator. Evaluation is as follows foldl op b [x 1,x 2,...,x n ] (x n (x 2 (x 1 b)) ) Examples fun rev xs = foldl op:: [] xs; > val rev = fn : a list -> a list rev [1,2,3]; > val it = [3, 2, 1] : int list c Michael R. Hansen, Spring 2005 p.59/59