Functional Paradigm II

Similar documents
Functional Paradigm II

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

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

Lecture 19: Functions, Types and Data Structures in Haskell

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

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

Exercises on ML. Programming Languages. Chanseok Oh

A quick introduction to SML

CSE 341 Section 5. Winter 2018

Inductive Data Types

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

Types and Type Inference

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

Structural polymorphism in Generic Haskell

Lists. Michael P. Fourman. February 2, 2010

How does ML deal with +?

SML A F unctional Functional Language Language Lecture 19

Principles of Programming Languages

CSE 307: Principles of Programming Languages

CSE 307: Principles of Programming Languages

CSE341 Spring 2017, Midterm Examination April 28, 2017

OCaml. ML Flow. Complex types: Lists. Complex types: Lists. The PL for the discerning hacker. All elements must have same type.

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

Announcements. CSCI 334: Principles of Programming Languages. Lecture 5: Fundamentals III & ML

A Brief Introduction to Standard ML

Haskell 5.1 INTERACTIVE SESSIONS AND THE RUN-TIME SYSTEM

Standard ML. Data types. ML Datatypes.1

Types and Type Inference

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

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

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

Introduction to ML. Based on materials by Vitaly Shmatikov. General-purpose, non-c-like, non-oo language. Related languages: Haskell, Ocaml, F#,

15 150: Principles of Functional Programming. More about Higher-Order Functions

Datatype declarations

According to Larry Wall (designer of PERL): a language by geniuses! for geniuses. Lecture 7: Haskell. Haskell 98. Haskell (cont) - Type-safe!

ML Built-in Functions

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

CSC/MAT-220: Lab 6. Due: 11/26/2018

Introduction to ML. Mooly Sagiv. Cornell CS 3110 Data Structures and Functional Programming

Chapter 15. Functional Programming. Topics. Currying. Currying: example. Currying: example. Reduction

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

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

All the operations used in the expression are over integers. a takes a pair as argument. (a pair is also a tuple, or more specifically, a 2-tuple)

Imperative languages

CSCC24 Functional Programming Typing, Scope, Exceptions ML

Handout 2 August 25, 2008

CSCI-GA Scripting Languages

Introduction to OCaml

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

Higher-Order Functions

Functional programming Primer I

cs242 Kathleen Fisher Reading: Concepts in Programming Languages, Chapter 6 Thanks to John Mitchell for some of these slides.

Haskell Types, Classes, and Functions, Currying, and Polymorphism

Lecture #23: Conversion and Type Inference

CSci 4223 Principles of Programming Languages

Conversion vs. Subtyping. Lecture #23: Conversion and Type Inference. Integer Conversions. Conversions: Implicit vs. Explicit. Object x = "Hello";

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

Currying fun f x y = expression;

Standard ML. Curried Functions. ML Curried Functions.1

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

CSci 4223 Lecture 12 March 4, 2013 Topics: Lexical scope, dynamic scope, closures

Introduction to SML Getting Started

301AA - Advanced Programming [AP-2017]

Types, Type Inference and Unification

CSE 3302 Programming Languages Lecture 8: Functional Programming

CSE 341 Sample Midterm #2

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

Logical Methods in... using Haskell Getting Started

Lecture #13: Type Inference and Unification. Typing In the Language ML. Type Inference. Doing Type Inference

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 Autumn 2017, Midterm Examination October 30, 2017

CSE341 Spring 2016, Midterm Examination April 29, 2016

Introduction to ML. Mooly Sagiv. Cornell CS 3110 Data Structures and Functional Programming

Programming Languages and Compilers (CS 421)

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

Typed Scheme: Scheme with Static Types

Haskell Refresher Informatics 2D

Principles of Programming Languages

CS 440: Programming Languages and Translators, Spring 2019 Mon

CS558 Programming Languages

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

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

CS558 Programming Languages

Data Types The ML Type System

Chapter 3 Linear Structures: Lists

CSE341, Fall 2011, Midterm Examination October 31, 2011

Overloading, Type Classes, and Algebraic Datatypes

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

CSE3322 Programming Languages and Implementation

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

The Algol family and ML

Haskell An Introduction

Chapter 3 Linear Structures: Lists

CS 320: Concepts of Programming Languages

INTRODUCTION TO HASKELL

CSE3322 Programming Languages and Implementation

Types-2. Polymorphism

Introduction to OCaml

Haskell 98 in short! CPSC 449 Principles of Programming Languages

CSE341 Spring 2016, Midterm Examination April 29, 2016

Transcription:

Processadors de Llenguatge II Functional Paradigm II Pratt A.7 Robert Harper s SML tutorial (Sec II) Rafael Ramirez Dep Tecnologia Universitat Pompeu Fabra

User-Defined Types How to define the new type. The principle in the use of data types (constructing via the data constructors, and deconstructing via pattern matching) is the same principle that you learnt in lists.

User-Defined Types In SML, the list is a predefined type constructor. The :: and [] are predefined data constructors. The value 1::(2::[]) has a type of int list. Which can be depicted conceptually as :: :: [ ] 1 2 Functions on list, deconstruct it by pattern matching fun len [] = 0 len (x::xs) = 1 + len xs The function len patternmatches by checking the data constructor first. Then it will know what things are stored. If it s a :: then it knows it can take out a head and tail. If it s a [ ], then it knows that there is no data stored there.

User-Defined Types In SML the list is a predefined type constructor. The :: and [] are predefined data constructors. The value 1::(2::[]) has a type of int list. Which can be depicted conceptually as :: :: [ ] 1 2 Functions on list, deconstruct it by pattern matching fun len [] = 0 len (x::xs) = 1 + len xs You can define your own type: datatype a mylist = mynil mycons of a * ( a mylist) Now, mylist is a user-defined type constructor. The mycons and mynil are the data constructors. The value mycons(1,mycons(2,mynil)) has a type of int mylist. Which can be depicted conceptually as mycons mycons 1 2 Functions on list, deconstruct it by pattern matching fun mylen mynil = 0 mylen (mycons(x,xs)) = 1 + mylen xs mynil

User-Defined Types datatype a mylist = mynil mycons of a * ( a mylist) datatype myintlist = intnil intcons of int * myintlist In defining a new datatype, you define A new type or a new type constructor. One or more data constructors.

User-Defined Types datatype a mylist = mynil mycons of a * ( a mylist) datatype myintlist = intnil intcons of int * myintlist In defining a new datatype, you define A new type or a new type constructor. One or more data constructors.

User-Defined Types datatype a mylist = mynil mycons of a * ( a mylist) mycons(1,mycons(2,mynil)) : int mylist Data constructors Type constructor Data expression Type expression

User-Defined Types datatype a mylist = mynil mycons of a * ( a mylist) mycons(1,mycons(2,mynil)) : int mylist mycons(1.1,mycons(2.2,mynil)) : real mylist mycons( a,mycons( b,mynil)):string mylist This is an example of PARAMETRIC POLYMORPHISM. It is when the type takes in another type as parameter.

User-Defined Types datatype a mylist = mynil mycons of a * ( a mylist) In general, the BNF for datatype declaration is: <DataDecl> ::= datatype [<tyvar>] <tyname> = <dataalt> { <dataalt>} <dataalt> ::= <Constructor> <Constructor> of <type> {* <type>} <Constructor> ::= <Identifier> <tyname> ::= <Identifier> <tyvar> ::= <Identifier>

User-Defined Types Binary Tree Defining an integer binary tree: datatype IntTree = Leaf of int Node of IntTree * int * IntTree <DataDecl> ::= datatype [<tyvar>] <tyname> = <dataalt> { <dataalt>} <dataalt> ::= <Constructor> <Constructor> of <type> {* <type>} <Constructor> ::= <Identifier> <tyname> ::= <Identifier> <tyvar> ::= <Identifier>

User-Defined Types Binary Tree Defining an integer binary tree: datatype IntTree = Leaf of int Node of IntTree * int * IntTree The above will declare A new type name : IntTree 2 new data constructors : Leaf, Node.

User-Defined Types Binary Tree Defining an integer binary tree: datatype IntTree = Leaf of int Node of IntTree * int * IntTree Constructing a tree using the user-defined data constructors: Leaf 26 Node (Leaf 26, 30, Leaf 10) Node (Leaf 26, 30, Node ( Leaf 10, 3, Leaf 4)) All will be of type IntTree

User-Defined Types Binary Tree Defining an integer binary tree: datatype IntTree = Leaf of int Node of IntTree * int * IntTree Deconstructing a tree through pattern matching: fun bsearch (Leaf y) y = y bsearch (Leaf _) _ = ~1 bsearch (Node (l,x,r)) y = if (y = x) then x (* return the value *) else if (y < x) then bsearch l y else bsearch r y;

User Defined DataTypes Parametric Polymorphism Defining a binary tree of some type: datatype a tree = Leaf of a Node of ( a tree) * a * ( a tree) Now we can have trees containing any type of object, but all objects stored must be the same type.

User Defined DataTypes Parametric Polymorphism Defining a binary tree of some type: datatype a tree = Leaf of a Node of ( a tree) * a * ( a tree) Constructing a tree using the user-defined data constructors: Leaf 1.33 : real tree Leaf 1 : int tree Node (Leaf 26, 30, Leaf 10) : int tree Node (Leaf [1], [2,3], Leaf [4]) : int list tree

User Defined DataTypes Parametric Polymorphism Defining a binary tree of some type: datatype a tree = Leaf of a Node of ( a tree) * a * ( a tree) Deconstructing a tree through pattern-matching: fun height (Leaf _) = 1 height (Node (l,_,r)) = 1 + max(height l, height r) height (Node (Node (Leaf 1,10,Leaf 2), 20 (Leaf 3))) Will evaluate to?.

User Defined DataTypes Parametric Polymorphism Defining a binary tree of some type: datatype a tree = Leaf of a Node of ( a tree) * a * ( a tree) Deconstructing a tree through pattern-matching: fun height (Leaf _) = 1 height (Node (l,_,r)) = 1 + max(height l, height r) height (Node (Node (Leaf 1,10,Leaf 2), 20 (Leaf 3))) Will evaluate to 3.

Types in ML Every expression will evaluate to a value. By the word value, we do not merely restrict ourselves to numbers, characters or booleans. For example, a list [1,2,3] is also considered as a value. In as much as 1 :: int so [1,2,3] :: int list Value Type (which is a set of values)

Types in ML Every value has a type. Therefore every expression written in ML can be assigned a type which is the type of the value it will evaluate to. If the expression that is written has a type or can be assigned a type, we say that: The expression is well-typed ; or The expression is typable (by the ML type system).

Types in ML Type Check vs Infer Type checking vs Type inferencing In most programming languages, we declare the type of an identifier, and the type system CHECKS that the program is type-safe. In ML, (most of the time) we need not declare the type of an identifier / expression, because the type system INFERS the type of the expression in the process of checking for type-safety.

Types in ML Declaring Exp Type However, if you insist on declaring the type of each expression, you may do so. <Exp> ::= <Constant> [: <type>] <Exp 1 > <op> <Exp 2 > [: <type>] if <Exp 0 > then <Exp 1 > else <Exp 2 > [: <type>] let {<Decl>} in <Exp> end [: <type>] <Exp 1 > <Exp 2 > [: <type>] fn <param> => <Exp> [: <type>] <TupleExp> [: <type>] <ListExp> [: <type>] <Identifier> [: <type>]

Types in ML BNF for types <type> ::= int real bool char string Primitive types names You have seen integers, reals and booleans. Here are examples of char and string types. - #"a"; val it = #"a" : char - #"a" : char; val it = #"a" : char - [#"a", #"b", #"c"]; val it = [#"a",#"b",#"c"] : char list - "a"; val it = "a" : string - "a":string; val it = "a" : string - ["a","b","c"]; val it = ["a","b","c"] : string list

Types in ML BNF for types <type> ::= int real bool char string <type> -> <type> Function Types Here are some examples: - (fn x => x + 1) : int -> int; val it = fn : int -> int - fun add x y z = x + y + z; val add = fn : int -> int -> int -> int - val add2 = (add 0) : int -> int -> int; val add2 = fn : int -> int -> int - val add3 = (add 5 6) : int -> int; val add3 = fn : int -> int

Types in ML BNF for types <type> ::= int real bool char string <type> -> <type> <type> * <type> { * <type> } Tuples (product types) Here are some examples: - (1,2) : int * int; val it = (1,2) : int * int - (1.2,3) : real * int; val it = (1.2,3) : real * int - ((#"a",2), 3.3, ("abc",true)) : ((char * int) * real * (string * bool)); val it = ((#"a",2),3.3,("abc",true)) : (char * int) * real * (string * bool)

Types in ML BNF for types <type> ::= int real bool char string <type> -> <type> <type> * <type> { * <type> } <typename> (User-Defined) Type names: Shown earlier with user-defined mylist and inttree. datatype IntTree = Leaf of int Node of IntTree * int * IntTree

Types in ML BNF for types <type> ::= int real bool char string <type> -> <type> <type> * <type> { * <type> } <typename> <type> <typecons> <typevar> Type constructors and type variables Examples: Shown earlier with a mylist. Here a is a type variable, and mylist is a type constructor,

Curried vs Uncurried Functions How many arguments does this function take? fun f(x,y) = x + 2 * y ; Ans : 1 argument, which is patternmatched to a pair. val f = fn : int * int -> int

Curried vs Uncurried Functions How many arguments does this function take? fun f x y = x + 2 * y ; Look at the type of the function: val f = fn : int -> int -> int Note that 1. the -> associates to the right. So the type is: val f = fn : int -> (int -> int) 2. Application associates to the left. So f 1 2 = ((f 1) 2)

Curried vs Uncurried Functions So from the type what can you deduce? How many arguments? val f = fn : int -> (int -> int) If you mean in the immediate sense, ONE argument is taken in by f. f a function which takes in an integer and returns a function. But if you mean eventually, when fully-applied, how many arguments does it take in, then f takes in a total of TWO arguments. f takes in an integer (1 st argument) which returns a function, which will take in another integer (2 nd argument), and return an integer.

Curried vs Uncurried Functions How many arguments does the function really take? fun f (x,y) = x + 2 * y ; pattern 1: a pair Ans: 1 argument which is pattern-matched to a pair fun f x y = x + 2 * y ; pattern 1 pattern 2 Ans: Eventually, when fully-applied, 2 arguments

Curried vs Uncurried Functions fun f (x,y) = x + 2 * y ; UNCURRIED FUNCTION You can convert any uncurried function to a curried version. This process is known as currying. curry is named after Haskell B. Curry fun f x y = x + 2 * y ; CURRIED FUNCTION The same fun f x = (fn y => x + 2 * y); val f = (fn x => (fn y => x + 2 * y));

Curried vs Uncurried Functions Curried functions provide extra flexibility to the language because it enables partial application of a function. fun twice f x = f (f x); let val inc2 = twice (fn x => x + x) in (inc2 1) + (inc2 2) end; val it = 12 ;

Curried vs Uncurried Functions Curried functions provide extra flexibility to the language because it enables partial application of a function. fun add_ver1 (x,y) = x+y; (* Uncurried *) fun add_ver2 x y = x+y; (* Curried *) map (add_ver1 10) [1,2,3,4,5] (* will not work *) map (add_ver2 10) [1,2,3,4,5] (* this will work*)