Inductive Data Types

Similar documents
Standard ML. Data types. ML Datatypes.1

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

Higher-Order Functions

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

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

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

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

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

Introduction to Typed Racket. The plan: Racket Crash Course Typed Racket and PL Racket Differences with the text Some PL Racket Examples

Lecture 19: Functions, Types and Data Structures in Haskell

Typed Racket: Racket with Static Types

Recursion. Lars-Henrik Eriksson. Functional Programming 1. Based on a presentation by Tjark Weber and notes by Sven-Olof Nyström

The Typed Racket Guide

Topic 7: Algebraic Data Types

CMSC 330: Organization of Programming Languages

Sum-of-Product (SOP) Datatypes in SML

CSCE 314 Programming Languages

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

Typed Scheme: Scheme with Static Types

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

Lists. Michael P. Fourman. February 2, 2010

Programming Languages

SML A F unctional Functional Language Language Lecture 19

Custom Types. Outline. COMP105 Lecture 19. Today Creating our own types The type keyword The data keyword Records

Recursion. Tjark Weber. Functional Programming 1. Based on notes by Sven-Olof Nyström. Tjark Weber (UU) Recursion 1 / 37

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

Structured programming

Recap: ML s Holy Trinity

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

Functional Paradigm II

CSC324 Functional Programming Typing, Exceptions in ML

CSCI-GA Scripting Languages

Overloading, Type Classes, and Algebraic Datatypes

CMSC 330: Organization of Programming Languages. OCaml Data Types

CSE 341 Section 5. Winter 2018

CS115 - Module 10 - General Trees

Recap: ML s Holy Trinity. Story So Far... CSE 130 Programming Languages. Datatypes. A function is a value! Next: functions, but remember.

CSE 130 Programming Languages. Datatypes. Ranjit Jhala UC San Diego

OCaml Data CMSC 330: Organization of Programming Languages. User Defined Types. Variation: Shapes in Java

Cornell University 12 Oct Solutions. (a) [9 pts] For each of the 3 functions below, pick an appropriate type for it from the list below.

CS558 Programming Languages

Handout 2 August 25, 2008

Module 9: Trees. If you have not already, make sure you. Read How to Design Programs Sections 14, 15, CS 115 Module 9: Trees

Sample Exam; Solutions

Consider the following EBNF definition of a small language:

CSE 130 Programming Languages. Lecture 3: Datatypes. Ranjit Jhala UC San Diego

Introduction to Functional Programming in OCaml

These are reserved words of the C language. For example int, float, if, else, for, while etc.

Tokens, Expressions and Control Structures

Recursion and Structural Induction

Recap from last time. Programming Languages. CSE 130 : Fall Lecture 3: Data Types. Put it together: a filter function

CSC324 Principles of Programming Languages

Chapter 3 Linear Structures: Lists

Types and Programming Languages. Lecture 5. Extensions of simple types

FUNCTIONAL PROGRAMMING NO.9 TYPE AND CLASS. Tatsuya Hagino

CSE 3302 Programming Languages Lecture 8: Functional Programming

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

Programming Paradigms

Chapter 3 Linear Structures: Lists

Haskell 5.1 INTERACTIVE SESSIONS AND THE RUN-TIME SYSTEM

Datatypes, Variables, and Operations

CS115 - Module 8 - Binary trees

CSCI.6962/4962 Software Verification Fundamental Proof Methods in Computer Science (Arkoudas and Musser) Chapter p. 1/27

Computer System and programming in C

Note first midterm date: Wed. evening, Feb. 23 Today's class: Types in OCaml and abstract syntax

Introduction to Programming, Aug-Dec 2006

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

Introduction to SML Getting Started

CS558 Programming Languages

A general introduction to Functional Programming using Haskell

UNIVERSITETET I OSLO

DaMPL. Language Reference Manual. Henrique Grando

APCS Semester #1 Final Exam Practice Problems

Chapter 6 Abstract Datatypes

Programming Languages. Datatypes

CS558 Programming Languages

Programming Languages. Next: Building datatypes. Suppose I wanted. Next: Building datatypes 10/4/2017. Review so far. Datatypes.

Haskell Overview III (3A) Young Won Lim 10/4/16

Functional Paradigm II

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

1.3b Type Conversion

Counting. Rosen, Chapter 6 Walls and Mirrors, Chapter 3

RSL Reference Manual

List Functions, and Higher-Order Functions

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

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

Functional Programming in Haskell Part 2 : Abstract dataypes and infinite structures

CSE3322 Programming Languages and Implementation

Exercises on ML. Programming Languages. Chanseok Oh

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

Lecture 2: The Basis of SML

Recap. Recap. If-then-else expressions. If-then-else expressions. If-then-else expressions. If-then-else expressions

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

Introduction to Objective Caml

Expressions. Eric Roberts Handout #3 CSCI 121 January 30, 2019 Expressions. Grace Murray Hopper. Arithmetic Expressions.

An introduction introduction to functional functional programming programming using usin Haskell

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

CSCC24 Functional Programming Typing, Scope, Exceptions ML

F28PL1 Programming Languages. Lecture 12: Standard ML 2

Transcription:

Inductive Data Types Lars-Henrik Eriksson Functional Programming 1 Original slides by Tjark Weber Lars-Henrik Eriksson (UU) Inductive Data Types 1 / 42

Inductive Data Types Today Today New names for old types New types Enumeration types Tagged unions Polymorphic data types Inductive data types Trees Lars-Henrik Eriksson (UU) Inductive Data Types 2 / 42

New Names for Old Types New Names for Old Types Lars-Henrik Eriksson (UU) Inductive Data Types 3 / 42

New Names for Old Types Type Bindings Type Bindings The keyword type gives a new name to an existing type. The simplest form is type identifier = type expression For instance, > type float = real; type float > type mylist = (char * int) list; type mylist = (char * int) list Lars-Henrik Eriksson (UU) Inductive Data Types 4 / 42

New Names for Old Types Type Bindings (cont.) Type Bindings (cont.) The new name becomes synonymous with the type expression. Both can be used interchangeably. For instance, > [(#"A", 1)] : mylist; val it = [(#"A", 1)]: mylist > ([(#"A", 1)] : mylist) = ([(#"A", 1)] : (char * int) list); val it = true: bool Lars-Henrik Eriksson (UU) Inductive Data Types 5 / 42

New Names for Old Types Parametric Type Bindings Parametric Type Bindings Types can be polymorphic, i.e., contain type variables. Therefore, type bindings can take type variables as parameters. The general form of a type binding is For instance, type ( type variables ) identifier = type expression > type ( a, b) assoc_list = ( a * b) list; type ( a, b) assoc_list = ( a * b) list Lars-Henrik Eriksson (UU) Inductive Data Types 6 / 42

New Names for Old Types Parametric Type Bindings (cont.) Parametric Type Bindings (cont.) All type variables that appear in the type expression (i.e., on the right) must be mentioned as a parameter (i.e., on the left). > type predicate = a -> bool; Error- a has not been declared in type declaration If there is just one parameter, the parentheses are optional. > type a predicate = a -> bool; type a predicate = a -> bool Type variables may be instantiated with types (as usual). > op< : (int * int) predicate; val it = fn: (int * int) predicate Lars-Henrik Eriksson (UU) Inductive Data Types 7 / 42

New Types New Types Lars-Henrik Eriksson (UU) Inductive Data Types 8 / 42

New Types Enumeration Types Enumeration Types The keyword datatype declares a new type. Here, we declare an enumeration type, i.e., a type that has a finite number of values C1,..., Cn: datatype identifier = C1... Cn For instance, > datatype direction = North South East West; datatype direction = East North South West > North; val it = North: direction Lars-Henrik Eriksson (UU) Inductive Data Types 9 / 42

New Types Enumeration Types: Example Enumeration Types: Example The types bool and unit each have a finite number of values. They could (in principle) be declared as enumeration types as follows: datatype bool = true false; datatype unit = (); Lars-Henrik Eriksson (UU) Inductive Data Types 10 / 42

New Types Enumeration Types: Exercise Enumeration Types: Exercise If we compare two integers a and b, then either (i) a < b, (ii) a = b, or (iii) a > b. 1 Declare an enumeration type order that has three values: LESS, EQUAL, GREATER. 2 Write a function compare: int * int -> order such that compare (a, b) returns LESS if a < b, EQUAL if a = b, and GREATER if a > b. Lars-Henrik Eriksson (UU) Inductive Data Types 11 / 42

New Types Enumeration Types: Exercise (cont.) Enumeration Types: Exercise (cont.) Solution: datatype order = LESS EQUAL GREATER (* compare (a, b) TYPE: int * int -> order PRE: true POST:... EX:... *) fun compare (a, b) = if a < b then LESS else if a = b then EQUAL else (* a > b *) GREATER order and Int.compare are already declared in the SML Basis Library. Lars-Henrik Eriksson (UU) Inductive Data Types 12 / 42

New Types Constructors Constructors In a datatype declaration datatype identifier = C1... C1,..., Cn are called constructors. Cn Coding convention: constructors begin with an uppercase letter (while functions and values begin with a lowercase letter). Lars-Henrik Eriksson (UU) Inductive Data Types 13 / 42

New Types Constructor Patterns Constructor Patterns Constructors can be used in patterns. A constructor matches only itself. For instance, (* opposite d TYPE: direction -> direction PRE: true POST: the direction opposite d EXAMPLES: opposite North = South *) fun opposite North = South opposite South = North opposite East = West opposite West = East Lars-Henrik Eriksson (UU) Inductive Data Types 14 / 42

New Types Constructor Patterns (cont.) Constructor Patterns (cont.) Constructors can be used in patterns. A constructor matches only itself. For instance, (* sign n TYPE: int -> int PRE: true POST: ~ 1 if n<0, 0 if n=0, 1 if n>0 EXAMPLES: sign 42 = 1 *) fun sign n = case Int.compare (n, 0) of LESS => ~ 1 EQUAL => 0 GREATER => 1 Lars-Henrik Eriksson (UU) Inductive Data Types 15 / 42

Beyond Enumeration Types Beyond Enumeration Types Lars-Henrik Eriksson (UU) Inductive Data Types 16 / 42

Beyond Enumeration Types Constructors with Arguments Constructors with Arguments Constructors in a datatype declaration may take arguments. These are indicated with they keyword of followed by the type of the argument. datatype identifier = C1 of type1... Cn of typen For instance, > datatype rational = Rat of int * int; datatype rational = Rat of int * int > Rat (2,3); val it = Rat (2, 3): rational Lars-Henrik Eriksson (UU) Inductive Data Types 17 / 42

Beyond Enumeration Types Constructors with Arguments: Pattern Matching Constructors with Arguments: Pattern Matching Constructors that take an argument can be used in patterns (together with a pattern for the argument). For instance, (* qadd (x, y) TYPE: rational * rational -> rational PRE: x and y are rational numbers (with denominator <> 0) POST: the sum of x and y EXAMPLES: qadd (Rat (1,2), Rat (1,3)) = Rat (5,6) *) fun qadd (Rat (a,b), Rat (c,d)) = Rat (a*d + b*c, b*d) Lars-Henrik Eriksson (UU) Inductive Data Types 18 / 42

Beyond Enumeration Types Example: Geometric Shapes Example: Geometric Shapes A type that models circles (of a given radius), squares (of a given side length) and triangles (of three given side lengths): datatype shape = Circle of real Square of real Triangle of real * real * real Note that Triangle(a,b,c) does not represent a real triangle in case the largest of the numbers a, b and c is greater than the sum of the other two numbers. Constructing values of type shape: > Circle 1.0; val it = Circle 1.0: shape > Square (1.0 + 1.0); val it = Square 2.0: shape > Triangle (3.0, 4.0, 5.0); val it = Triangle (3.0, 4.0, 5.0): shape Lars-Henrik Eriksson (UU) Inductive Data Types 19 / 42

Beyond Enumeration Types Example: Geometric Shapes (cont.) Example: Geometric Shapes (cont.) A function that computes the area of a geometric shape: (* area s TYPE: shape -> real PRE: If s is Triangle(a,b,c) then it must represent actual triangle. POST: the area of s EXAMPLES: area (Circle 1.0) = 3.141592654 *) fun area (Circle r) = Math.pi * r * r area (Square l) = l * l area (Triangle (a, b, c)) = let val s = (a + b + c) / 2.0 in (* Heron s formula *) Math.sqrt (s * (s-a) * (s-b) * (s-c)) end Lars-Henrik Eriksson (UU) Inductive Data Types 20 / 42

Beyond Enumeration Types The Type of Constructors The Type of Constructors A constructor that takes no arguments has the declared type. > North; val it = North: direction A constructor that takes an argument has a function type. > Circle; val it = fn: real -> shape > Square; val it = fn: real -> shape > Triangle; val it = fn: real * real * real -> shape However, constructors (unlike functions) can be used in patterns! Lars-Henrik Eriksson (UU) Inductive Data Types 21 / 42

Beyond Enumeration Types Tagged Unions/Sum Types Tagged Unions/Sum Types Types declared via datatype identifier = C1 of type1... Cn of typen are also known as tagged unions or sum types. We can think of values of this type as either being a value of type 1 or... or a value of type N, that is tagged with a constructor that indicates which type the value has. Lars-Henrik Eriksson (UU) Inductive Data Types 22 / 42

Beyond Enumeration Types Polymorphic Data Types Polymorphic Data Types The argument types of constructors can be polymorphic, i.e., contain type variables. Therefore, datatype declarations can take type variables as parameters. The general form of a datatype declaration is datatype ( type variables ) identifier = C1 of type1... Cn of typen Lars-Henrik Eriksson (UU) Inductive Data Types 23 / 42

Beyond Enumeration Types Example: a option Example: a option For instance, > datatype ( a) option = NONE SOME of a; datatype a option = NONE SOME of a > NONE; val it = NONE: a option > SOME; val it = fn: a -> a option > SOME 42; val it = SOME 42: int option > SOME "foo"; val it = SOME "foo": string option > SOME []; val it = SOME []: a list option Lars-Henrik Eriksson (UU) Inductive Data Types 24 / 42

Beyond Enumeration Types The Option Type The Option Type We can think of values of type a option as representing either a single value or zero values of type a. Type a option is useful to model partial functions (i.e., functions that normally return a value of type a, but may not do so for some argument values). For instance, not every string corresponds to an integer value: > Int.fromString "42"; val it = SOME 42: int option > Int.fromString "foo"; val it = NONE: int option a option is more explicit than exceptions. (It requires callers to deal with the NONE case explicitly.) This may or may not be desirable. a option and related functions are declared in the SML Basis Library. Lars-Henrik Eriksson (UU) Inductive Data Types 25 / 42

Beyond Enumeration Types Polymorphic Data Types (cont.) Polymorphic Data Types (cont.) All type variables that appear in an argument type (i.e., on the right) must be mentioned as a parameter (i.e., on the left). > datatype option = NONE SOME of a; Error- a has not been declared in type declaration If there is just one parameter, the parentheses are optional. > datatype a option = NONE SOME of a; datatype a option = NONE SOME of a Type variables may be instantiated with types (as usual). > NONE : int option; val it = NONE: int option Lars-Henrik Eriksson (UU) Inductive Data Types 26 / 42

Inductive Data Types Inductive Data Types Lars-Henrik Eriksson (UU) Inductive Data Types 27 / 42

Inductive Data Types Inductive Data Types Inductive Data Types The argument types of constructors may refer to (instances of) the data type that is being declared. That is, in a datatype declaration datatype ( type variables ) identifier = C1 of type1... Cn of typen the expressions type1,... typen may contain identifier applied to (the correct number of) type parameters. Lars-Henrik Eriksson (UU) Inductive Data Types 28 / 42

Inductive Data Types Example: a list Example: a list The type a list of lists (with elements from a) is an inductive type. 1 Base case: [] : a list 2 Inductive step: If x : a and xs : a list, then x :: xs : a list. a list could (in principle) be declared as follows: datatype a list = [] :: of a * a list Lars-Henrik Eriksson (UU) Inductive Data Types 29 / 42

Inductive Data Types Example: Arithmetic Expressions Example: Arithmetic Expressions For instance, 1 + 2, 3 4 + 5,... Let us define arithmetic expressions (that involve addition and multiplication over integers) inductively: 1 Base case: Each integer is an arithmetic expression (aexp). 2 Inductive step: If e 1 and e 2 are aexps, then e 1 + e 2 is an aexp. If e 1 and e 2 are aexps, then e 1 e 2 is an aexp. Lars-Henrik Eriksson (UU) Inductive Data Types 30 / 42

Inductive Data Types Example: Arithmetic Expressions Example: Arithmetic Expressions For instance, 1 + 2, 3 4 + 5,... Let us define arithmetic expressions (that involve addition and multiplication over integers) inductively: 1 Base case: Each integer is an arithmetic expression (aexp). 2 Inductive step: If e 1 and e 2 are aexps, then e 1 + e 2 is an aexp. If e 1 and e 2 are aexps, then e 1 e 2 is an aexp. datatype aexp = Int of int Plus of aexp * aexp Times of aexp * aexp Lars-Henrik Eriksson (UU) Inductive Data Types 30 / 42

Inductive Data Types Example: Evaluation of Arithmetic Expressions Example: Evaluation of Arithmetic Expressions datatype aexp = Int of int Plus of aexp * aexp Times of aexp * aexp (* eval e TYPE: aexp -> int PRE: true POST: the value of e EXAMPLES: eval (Plus (Int 1, Int 2)) = 3 *) Lars-Henrik Eriksson (UU) Inductive Data Types 31 / 42

Inductive Data Types Example: Evaluation of Arithmetic Expressions Example: Evaluation of Arithmetic Expressions datatype aexp = Int of int Plus of aexp * aexp Times of aexp * aexp (* eval e TYPE: aexp -> int PRE: true POST: the value of e EXAMPLES: eval (Plus (Int 1, Int 2)) = 3 *) (* VARIANT: size of e *) fun eval (Int i) = i eval (Plus (x, y)) = eval x + eval y eval (Times (x, y)) = eval x * eval y Lars-Henrik Eriksson (UU) Inductive Data Types 31 / 42

Inductive Data Types Data Types: Structural Equality Data Types: Structural Equality Equality of datatype values is structural. Two values of the same datatype are equal if (and only if) they are built by the same constructor applied to equal arguments. For instance, > Int 1 = Int 1; Lars-Henrik Eriksson (UU) Inductive Data Types 32 / 42

Inductive Data Types Data Types: Structural Equality Data Types: Structural Equality Equality of datatype values is structural. Two values of the same datatype are equal if (and only if) they are built by the same constructor applied to equal arguments. For instance, > Int 1 = Int 1; val it = true: bool > Int 1 = Int 2; Lars-Henrik Eriksson (UU) Inductive Data Types 32 / 42

Inductive Data Types Data Types: Structural Equality Data Types: Structural Equality Equality of datatype values is structural. Two values of the same datatype are equal if (and only if) they are built by the same constructor applied to equal arguments. For instance, > Int 1 = Int 1; val it = true: bool > Int 1 = Int 2; val it = false: bool > Plus (Int 1, Int 2) = Int 3; Lars-Henrik Eriksson (UU) Inductive Data Types 32 / 42

Inductive Data Types Data Types: Structural Equality Data Types: Structural Equality Equality of datatype values is structural. Two values of the same datatype are equal if (and only if) they are built by the same constructor applied to equal arguments. For instance, > Int 1 = Int 1; val it = true: bool > Int 1 = Int 2; val it = false: bool > Plus (Int 1, Int 2) = Int 3; val it = false: bool > Plus (Int 1, Int 2) = Plus (Int 1, Int 2); Lars-Henrik Eriksson (UU) Inductive Data Types 32 / 42

Inductive Data Types Data Types: Structural Equality Data Types: Structural Equality Equality of datatype values is structural. Two values of the same datatype are equal if (and only if) they are built by the same constructor applied to equal arguments. For instance, > Int 1 = Int 1; val it = true: bool > Int 1 = Int 2; val it = false: bool > Plus (Int 1, Int 2) = Int 3; val it = false: bool > Plus (Int 1, Int 2) = Plus (Int 1, Int 2); val it = true: bool Lars-Henrik Eriksson (UU) Inductive Data Types 32 / 42

Inductive Data Types Not All Data Types Are Equality Types Not All Data Types Are Equality Types Suppose type t is declared via datatype ( type variables ) t = C1 of type1... Cn of typen An instance (t1,..., tk) t is an equality type if t1,..., tk are equality types and the instances of type1,..., typen are equality types. For instance, > Circle 1.0 = Square 1.0; Lars-Henrik Eriksson (UU) Inductive Data Types 33 / 42

Inductive Data Types Not All Data Types Are Equality Types Not All Data Types Are Equality Types Suppose type t is declared via datatype ( type variables ) t = C1 of type1... Cn of typen An instance (t1,..., tk) t is an equality type if t1,..., tk are equality types and the instances of type1,..., typen are equality types. For instance, > Circle 1.0 = Square 1.0; Error-Type error in function application. Function: = : a * a -> bool Argument: (Circle 1.0, Square 1.0) : shape * shape Reason: Can t unify a to shape (Requires equality type) Lars-Henrik Eriksson (UU) Inductive Data Types 33 / 42

Inductive Data Types Not All Data Types Are Equality Types (cont.) Not All Data Types Are Equality Types (cont.) datatype a option = NONE SOME of a > NONE = SOME 1.0; Lars-Henrik Eriksson (UU) Inductive Data Types 34 / 42

Inductive Data Types Not All Data Types Are Equality Types (cont.) Not All Data Types Are Equality Types (cont.) datatype a option = NONE SOME of a > NONE = SOME 1.0; Error-Type error in function application. Function: = : a option * a option -> bool Argument: (NONE, SOME 1.0) : a option * real option Reason: Can t unify a to real (Requires equality type) > NONE = SOME 1; Lars-Henrik Eriksson (UU) Inductive Data Types 34 / 42

Inductive Data Types Not All Data Types Are Equality Types (cont.) Not All Data Types Are Equality Types (cont.) datatype a option = NONE SOME of a > NONE = SOME 1.0; Error-Type error in function application. Function: = : a option * a option -> bool Argument: (NONE, SOME 1.0) : a option * real option Reason: Can t unify a to real (Requires equality type) > NONE = SOME 1; val it = false: bool Lars-Henrik Eriksson (UU) Inductive Data Types 34 / 42

Trees Trees Lars-Henrik Eriksson (UU) Inductive Data Types 35 / 42

Trees Full Binary Trees Full Binary Trees A tree where each inner node has exactly two children is called a full binary tree. Lars-Henrik Eriksson (UU) Inductive Data Types 36 / 42

Trees Full Binary Trees: Inductive Definition Full Binary Trees: Inductive Definition Full binary trees (with labels of type a) can be defined inductively: 1 Base case: Each value of type a is a full binary tree, namely a leaf. 2 Inductive step: If x is of type a and t 1 and t 2 are full binary trees, then Node (t 1, x, t 2 ) is a full binary tree. In SML: Lars-Henrik Eriksson (UU) Inductive Data Types 37 / 42

Trees Full Binary Trees: Inductive Definition Full Binary Trees: Inductive Definition Full binary trees (with labels of type a) can be defined inductively: 1 Base case: Each value of type a is a full binary tree, namely a leaf. 2 Inductive step: If x is of type a and t 1 and t 2 are full binary trees, then Node (t 1, x, t 2 ) is a full binary tree. In SML: datatype a fbtree = Leaf of a Node of a fbtree * a * a fbtree Lars-Henrik Eriksson (UU) Inductive Data Types 37 / 42

Trees Full Binary Trees: Examples Full Binary Trees: Examples datatype a fbtree = Leaf of a Node of a fbtree * a * a fbtree Some full binary trees in SML: > Leaf "Grandfather"; val it = Leaf "Grandfather": string fbtree > Node (Leaf "Grandfather", "Father", Leaf "Grandmother"); val it = Node (Leaf "Grandfather", "Father", Leaf "Grandmother"): string fbtree Lars-Henrik Eriksson (UU) Inductive Data Types 38 / 42

Trees Pattern Matching: Example Pattern Matching: Example Functions over trees like functions over inductive data types in general are usually defined using pattern matching and recursion. For instance, (* root_value t TYPE: a fbtree -> a PRE: true POST: the value at t s root node EXAMPLES: root_value (Leaf "foo") = "foo" *) Lars-Henrik Eriksson (UU) Inductive Data Types 39 / 42

Trees Pattern Matching: Example Pattern Matching: Example Functions over trees like functions over inductive data types in general are usually defined using pattern matching and recursion. For instance, (* root_value t TYPE: a fbtree -> a PRE: true POST: the value at t s root node EXAMPLES: root_value (Leaf "foo") = "foo" *) fun root_value (Leaf x) = x root_value (Node (_, x, _)) = x Lars-Henrik Eriksson (UU) Inductive Data Types 39 / 42

Trees Tree Height in SML Tree Height in SML (* height t TYPE: a fbtree -> int PRE: true POST: the height of t EXAMPLES: height (Leaf "foo") = 0 *) Lars-Henrik Eriksson (UU) Inductive Data Types 40 / 42

Trees Tree Height in SML Tree Height in SML (* height t TYPE: a fbtree -> int PRE: true POST: the height of t EXAMPLES: height (Leaf "foo") = 0 *) (* VARIANT: size of t *) fun height (Leaf _) = 0 height (Node (l, _, r)) = 1 + Int.max (height l, height r) Lars-Henrik Eriksson (UU) Inductive Data Types 40 / 42

Trees Mirror Image Mirror Image Let s write a function that mirrors a full binary tree by (recursively) exchanging left and right subtrees. For instance, Lars-Henrik Eriksson (UU) Inductive Data Types 41 / 42

Trees Mirror Image in SML Mirror Image in SML (* mirror t TYPE: a fbtree -> a fbtree PRE: true POST: the mirror image of t EXAMPLES: mirror (Node (Leaf 1, 2, Leaf 3)) = Node (Leaf 3, 2, Leaf 1) *) Lars-Henrik Eriksson (UU) Inductive Data Types 42 / 42

Trees Mirror Image in SML Mirror Image in SML (* mirror t TYPE: a fbtree -> a fbtree PRE: true POST: the mirror image of t EXAMPLES: mirror (Node (Leaf 1, 2, Leaf 3)) = Node (Leaf 3, 2, Leaf 1) *) (* VARIANT: size of t *) fun mirror (Leaf x) = Leaf x mirror (Node (l, x, r)) = Node (mirror r, x, mirror l) Lars-Henrik Eriksson (UU) Inductive Data Types 42 / 42