F28PL1 Programming Languages Lecture 13: Standard ML 3.

Slides:



Advertisements
Similar presentations
Modern Programming Languages, 2nd ed.
Advertisements

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 First Look at ML.
A Third Look At ML 1. Outline More pattern matching Function values and anonymous functions Higher-order functions and currying Predefined higher-order.
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists Dan Grossman Winter 2013.
F28PL1 Programming Languages Lecture 14: Standard ML 4.
CMSC 330: Organization of Programming Languages Tuples, Types, Conditionals and Recursion or “How many different OCaml topics can we cover in a single.
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.
ML Datatypes.1 Standard ML Data types. ML Datatypes.2 Concrete Datatypes  The datatype declaration creates new types  These are concrete data types,
ML Datatypes.1 Standard ML Data types. ML Datatypes.2 Concrete Data  Consists of constructions that can be inspected, taken apart, or joined to form.
Getting started with ML ML is a functional programming language. ML is statically typed: The types of literals, values, expressions and functions in a.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
Chapter ElevenModern Programming Languages1 A Fourth Look At ML.
A Fourth Look At ML Chapter ElevenModern Programming Languages, 2nd ed.1.
A First Look at ML Chapter FiveModern Programming Languages, 2nd ed.1.
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.
5/11/2015IT 3271 Types in ML (Ch 11) datatype bool = true | false; datatype 'element list = nil | :: of 'element * 'element list n Predefined, but not.
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.
Introduction to ML Last time: Basics: integers, Booleans, tuples,... simple functions introduction to data types This time, we continue writing an evaluator.
Introduction to ML You will be responsible for learning ML on your own. Today I will cover some basics Read Robert Harper’s notes on “an introduction to.
CSE 341 Lecture 6 exceptions; higher order functions; map, filter, reduce Ullman 5.2, 5.4 slides created by Marty Stepp
Functional Design and Programming Lecture 4: Sorting.
1 Functional Programming and ML. 2 What’s wrong with Imperative Languages? State State Introduces context sensitivity Introduces context sensitivity Harder.
CS 2104 : Prog. Lang. Concepts. Functional Programming I Lecturer : Dr. Abhik Roychoudhury School of Computing From Dr. Khoo Siau Cheng’s lecture notes.
Functional Programming Element of Functional Programming.
ML Datatypes.1 Standard ML Data types. ML Datatypes.2 Concrete Datatypes  The datatype declaration creates new types  These are concrete data types,
F28PL1 Programming Languages Lecture 15: Standard ML 5.
Strings The Basics. Strings can refer to a string variable as one variable or as many different components (characters) string values are delimited by.
Introduction to Functional Programming and ML CS 331 Principles of Programming Languages.
Fall Week 4 CSCI-141 Scott C. Johnson.  Computers can process text as well as numbers ◦ Example: a news agency might want to find all the articles.
Chapter 9: Functional Programming in a Typed Language.
Built-in Data Structures in Python An Introduction.
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.
1 Functional Programming Lecture 6 - Algebraic Data Types.
A Second Look At ML 1. Outline Patterns Local variable definitions A sorting example 2.
Overview of the Haskell 98 Programming Language
PZ03EX Programming Language design and Implementation -4th Edition Copyright©Prentice Hall, PZ03EX - ML Programming Language Design and Implementation.
A Third Look At ML Chapter NineModern Programming Languages, 2nd ed.1.
Error Example - 65/4; ! Toplevel input: ! 65/4; ! ^^ ! Type clash: expression of type ! int ! cannot have type ! real.
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:
CSED101 INTRODUCTION TO COMPUTING SUM TYPE 유환조 Hwanjo Yu.
What are Operators? Some useful operators to get you started.
Haskell Chapter 5, Part II. Topics  Review/More Higher Order Functions  Lambda functions  Folds.
1 Objective Caml (Ocaml) Aaron Bloomfield CS 415 Fall 2005.
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.
1 ENERGY 211 / CME 211 Lecture 3 September 26, 2008.
Principles of programming languages 12: Functional programming
Types CSCE 314 Spring 2016.
ML: a quasi-functional language with strong typing
Functions and patterns
ML Again ( Chapter 7) Patterns Local variable definitions
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
ML Programming Language Design and Implementation (4th Edition)
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
Functions, Patterns and Datatypes
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
CSE 341 Section 5 Winter 2018.
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
Functions, Patterns and Datatypes
CSE-321 Programming Languages Introduction to Functional Programming
Functions, Patterns and Datatypes
Functions and patterns
CSE341: Programming Languages Lecture 2 Functions, Pairs, Lists
PROGRAMMING IN HASKELL
Functions, Patterns and Datatypes
Presentation transcript:

F28PL1 Programming Languages Lecture 13: Standard ML 3

Type variable all types so far have been ground – i.e. all details known SML provides type variables to express unknown types Greek names –  - alpha - written ‘a –  - beta - written ‘b –  - gamma - written ‘c – etc

Type variable in a type expression, all occurrences of the same type variable must refer to the same type e.g. ‘a * ‘a * ‘a tuple with 3 elements of same unknown type all ‘a refer to same type satisfied by: (1,2,3) : int * int * int i.e. ‘a == int

Type variable e.g. ‘a * ‘a * ‘a satisfied by: ((1,”one”),(2,”two”),(3,”three”)) : (int * string)*(int*string)* int*string ) i.e. ‘a == int * string

Type variable e.g. (‘a * ‘b) * (‘a * ‘b) tuple with 2 elements of same type 1st sub-element of each sub-tuple have same unknown type – ‘a could be any type 2nd sub-element of each sub-tuple have same unknown type – ‘b could be any type ‘a and ‘b could refer to same type but need

Type variable e.g. (‘a * ‘b) * (‘a * ‘b) satisfied by: ((“Francis”,1.7),(“Frances”,1.65)) : (string * real) * (string * real) i.e. ‘a == string, ‘b == real ((1,(“even”,false)),(2,(”even”,true))) : (int*(string*bool))*int*(string*bool)) i.e. ‘a == int, ‘b == string * bool ((1,1),(2,4)) : (int * int) * (int * int ) i.e. ‘a == ‘b == int

Tuple pattern extend patterns to include tuples of patterns e.g. join two strings in tuple together with a space in between - fun tJoin (s1,s2) = s1^” “^s2; > val tJoin = fn : string * string -> string ^ takes 2 string s so s1 and s2 must be string - tJoin (“hello”,”there”); > “hello there” : string

Tuple pattern e.g. swap elements of pair tuple - swap (e1,e2) = (e2,e1); > val swap = fn : ‘a * ‘b -> ‘b * ‘a can’t deduce type for e1 ; call it ‘a can’t deduce type for e2 ; call it ‘b - swap (1,”two”); > (“two”,1) : string * int for ‘a * ‘b to be consistent with (1,”two”) : int * string ‘a must be int ; ‘b must be string

Tuple pattern - swap ((1,”two”),(”one”,2)); > ((“one”,2),(1,”two”) : (string * int) * (int * string) swap : ‘a * ‘b -> ‘b * ‘a for a * ‘b to be consistent with ((1,”two”),(”one”,2)) : (int * string) * (string * int ) ‘a must be int * string ‘b must be string * int

Tuple pattern e.g. select first element from 2 element tuple - fun first (e1,_) = e1 > val first = fn : ‘a * ‘b -> ‘a - first (“hello”,”there”); > “hello” : string e.g. select second from 2 element tuple - fun second (_,e2) = e2 > val second = fn : ‘a * ‘b -> ‘b - second (true,42); > 42 : int

Lists arbitrary length sequence of same type if ‘a is a type then ‘a list is a list of ‘a lists are polymorphic – list of any type, including lists & functions empty list – [] or nil list constructor: :: - infix binary if h is ‘a and t is ‘a list then h :: t is ‘a list h is head of list t is tail of list

Lists NB all lists must end with empty list system shows list in bracketed shorthand elem 1 ::( elem 2 ::... ( elem N ::[])... ) ==> [ elem 1, elem 2...elem N ] - 1::(2::(3::[])); > [1,2,3] : int list - “Ann”::(“Bill”::(“Cyd”::[])); > [“Ann”,”Bill”,”Cyd”] : string list

Lists don’t need (... ) with :: - (1,”one”)::(2,”two”)::(3,”three”)::[]; > [(1,”one”),(2,”two”),(3,”three”)] : (int * string) list singleton list elem ::[] ==> [ elem ] - 42::[]; > [42] : int list :: has lower precedence than function calls

Lists e.g. generate list of integers from n to 1 - fun ints 0 = [] | ints n = n::ints (n-1); > val ints = fn : int -> int list 0 is int so n must be int n is int so :: must return int list - ints 4; > [4,3,2,1] : int list ints 4 ==> 4::ints 3 ==> 4::3::ints 2 ==> 4::3::2::ints 1 ==> 4::3::2::1::ints 0 ==> 4::3::2::1::[] ==> [4,3,2,1]

Lists e.g. generate list with n copies of value s base case: n=0 ==> return empty list recursion case: n>0 ==> put s on front of n-1 copies of s - fun nCopies 0 _ = [] | nCopies n s = s::nCopies (n-1) s; > val nCopies = fn : int -> ‘a -> ‘a list 0 is int so n must be int don’t know s ’s type; call it ‘a ; :: returns ‘a list

Lists - nCopies 3 “o”; > [“o”,”o”,”o”] : string list nCopies : int -> ‘a -> ‘a list to be consistent when s is a string, ‘a == string nCopies 3 “o” ==> “o”::nCopies 2 “o” ==> “o”::”o”::nCopies 1 “o” ==> “o”::”o”::”o”::nCopies 0 “o” ==> “o”::”o”::”o”::[] ==> [“o”,”o”,”o”]

Lists - nCopies 3 9; > [9,9,9] : int list nCopies : int -> ‘a -> ‘a list to be consistent when s is an int, ‘a == int nCopies 3 9 ==> 9::nCopies 2 9 ==> 9::9::nCopies 1 9 ==> 9::9::9::nCopies 0 9 ==> 9::9::9::[] ==> [9,9,9]

Recursion 2: lists list is either – empty – non-empty with a head and a tail can use list patterns in function definitions use [] as a constant make patterns with other patterns and :: ( h :: t ) – h is a pattern to match list head – t is a pattern to match list tail must be bracketed

Recursion 2: lists recursion on lists base case: [] – return final value recursion case: ( h :: t ) – do something to h – recurse on t e.g. sum elements of integer list base case: [] ==> 0 recursion case: (h::t ) ==> add h to summing t

Recursion 2: lists - fun sum [] = 0 | sum (h::t) = h+sum t; > int list -> int 0 is int so... + must be int addition so... h must be in t so... h::t must be int list

Recursion 2: lists - sum [2,4,6]; > 12 : int sum [2,4,6] ==> sum 2::[4,6] ==> 2+sum [4,6] ==> 2+sum 4::[6] ==> 2+4+sum [6] ==> 2+4+sum 6::[] ==> sum [] ==> ==> 12

Recursion 2: lists e.g. join all strings in list base case: [] ==> “” recursion case: (h::t) ==> join h to joining up all in t - fun sJoin [] = “” | sJoin (h::t) = h^sJoin t; > val sJoin =fn : string list -> string ^ takes 2 string s so h must be string so h:: t must be string list

Recursion 2: lists - sJoin [“a”,”bc”,”def”]; > “abcdef” : string sJoin [“a”,”bc”,”def”] ==> sJoin “a”::[“bc”,”def”] ==> “a”^sJoin [“bc”,”def”] ==> “a”^sJoin “bc”::[“def] ==> “a”^”bc”^sJoin [“def”] ==> “a”^”bc”^sJoin “def”::[] ==> “a”^”bc”^”def”^sJoin [] ==> “a”^”bc”^”def”^”” ==> “abcdef”

Recursion 2: lists e.g. double all elements of integer list base case: [] ==> [] recursion case: (h::t ) ==> put twice h onto list from doubling all t - fun double [] = [] | double (h::t) = 2*h::double t; > val double = fn : int list -> int list 2 is int so * must be int so h must be int so h::t must be int list :: must be int list construction

Recursion 2: lists - double [5,3,1]; > [10,6,2] : int list double [5,3,1] ==> 2*5::double [3,1] ==> 2*5::2*3::double [1] ==> 2*5::2*3::2*1::double [] ==> 2*5::2*3::2*1::[] ==> [10,6,2]

Recursion 2: lists e.g. count how often 0 appears in a list base case: [] ==> 0 recursion case1: (h::t) - h =0 ==> 1 + count 0 in t recursion case 2: (h::t) - h <>0 ==> count 0 in t - fun count0 [] = 0 | count0 (0::t) = 1+count0 t | count0 (_::t) = count0 t; > val count0 = fn : int list -> int 0 is int so 0::t must be int list 0 is int so + must be int addition

Recursion 2: lists - count0 [1,0,2,0,3,0]; > 3 : int count0 [1,0,2,0,3,0] ==> count0 [0,2,0,3,0] ==> 1+count0 [2,0,3,0] ==> 1+count0 [0,3,0] ==> 1+1+count0 [3,0] ==> 1+1+count0 [0] ==> count0 [] ==> ==> 3

Equality type e.g. count how often value v appears in list base case: [] ==> 0 recursion case1: (h::t) - h = v ==> 1 + count v in t recursion case2: (h::t) - h <> v ==> count v in t - fun count _ [] = 0 | count v (h::t) = if v=h then 1+count v t else count v t; > val count = fn : ‘’a -> ‘’a list -> int

Equality type - fun count _ [] = 0 | count v (h::t) = if v=h then 1+count v t else count v t; > val count = fn : ‘’a -> ‘’a list -> int ‘’a - equality type variable don’t know anything about v, h or t know that v and h are the same equality type, say ‘’a, so h::t must be a ‘’a list

Equality type - count “a” [“a”,”b”,”a”]; > 2 : int count :: ‘’a -> ‘’a list -> int for consistency when v is “a” and (h::t) is [“a”,”b”,”a”], ‘’a must be string count “a” [“a”,”b”,”a”] ==> 1+count “a” [“b”,”a”] ==> 1+count “a” [“a”] ==> 1+1+count”a” [] ==> ==> 2

Accumulation variables used to pass information from stage to stage of recursion e.g. count how many integer list elements are negative, zero or positive use a tuple to record counts: (negative,zero,positive) pass tuple from call to call at end of list return tuple

Accumulation variables base case: [] ==> return counts tuple recursion case1: (h::t) – h =0 ==> find counts for t with zero count incremented recursion case2: (h::t) – h find counts for t with negative count incremented recursion case3: (h::t) – h >0 ==> find counts for t with positive count incremented

Accumulation variables - fun counts (n,z,p) [] = (n,z,p) | counts (n,z,p) (0::t) = counts (n,z+1,p) t | counts (n,z,p) (h::t) = if h<0 then counts (n+1,z,p) t else counts (n,z,p+1) t; > val counts = fn : int * int * int -> int list -> int * int * int

Accumulation variables - counts (0,0,0) [1,~2,0,3,~4]; > (2,1,2) : int * int * int counts (0,0,0) [1,~2,0,3,~4] ==> counts (0,0,1) [~2,0,3,~4] ==> counts (1,0,1) [0,3,~4] ==> counts (1,1,1) [3,~4] ==> counts (1,1,2) [~4] ==> counts (2,1,2) [] ==> (2,1,2) NB can’t update individual fields of tuple must copy tuple with changes

Accumulation variables e.g. generate list of squares from m to n in ascending order base case: m > n ==> return [] recursion case m put m squared onto list of squares from m+1 to n - fun squares m n = if m>n then [] else sq m::squares (m+1) n; > val squares = fn : int -> int -> int list

Accumulation variables - squares 1 4; > [1,4,9,16] : int list squares 1 4 ==> sq 1::squares 2 4 ==> sq 1::sq 2::squares 3 4 ==> sq 1::sq 2::sq 3::squares 4 4 ==> sq 1::sq 2::sq 3::sq 4::squares 5 4 ==> sq 1::sq 2::sq 3::sq 4::[] ==> [1,4,9,16] m is accumulation variable to pass start of new range from call to call

Local definitions let definition in expression end definition establishes name/value associations for use in expression only scope of definition is expression - let val x = 12 in x*x*x end; > 1728 : int

Local definitions very useful for tuple matching and selection - let val ((given,family),age) = ((“Clark”,”Kent”),29) in given end; > “Clark” : string particularly useful when function returns tuple and only want some elements NB don’t forget: – val before variable – end at end of definition

Exceptions break flow of control typically after some error when exception is raised – control is transferred to handler exception identifier defines an exception with type constructor identifier

Exceptions raise identifier initiates the exception transfers control to immediately enclosing handler if no handler then control is transferred to the system and program stops e.g. divide by 0 - exception DIVIDE_BY_ZERO; > exception DIVIDE_BY_ZERO

Exceptions - fun divide x y = if y=0 then raise DIVIDE_BY_ZERO else x div y; > val divide = fn: int -> int - divide 3 0; > exception DIVIDE_BY_ZERO uncaught exception DIVIDE_BY_ZERO

Type aliases type aliases type identifier = type expression identifier is an alias for type expression i.e. both denote same type

Type aliases - type family = string; > type family = sting - type given = string; > type given = string - type person = family * given; > type person = family * given - type people = person list; > type people = person list family and given are both aliases for string

Type aliases - type family = string; > type family = sting - type given = string; > type given = string - type person = family * given; > type person = family * given - type people = person list; > type people = person list person is an alias for family * given is an alias for string * string

Type aliases - type family = string; > type family = sting - type given = string; > type given = string - type person = family * given; > type person = family * given - type people = person list; > type people = person list people is an alias for person list is an alias for (family * given ) list is an alias for (string * string ) list

NJSML print depth NJSML will only print data structures to fixed depth thereafter indicates unprinted structure with # to change print depth: - Control.Print.printDepth := integer;