Functional Programming



Similar documents
Functional Programming. Functional Programming Languages. Chapter 14. Introduction

Chapter 15 Functional Programming Languages

CSE 307: Principles of Programming Languages

Lecture 1: Introduction

CSCI 3136 Principles of Programming Languages

High-Level Programming Languages. Nell Dale & John Lewis (adaptation by Michael Goldwasser)

Chapter 7: Functional Programming Languages

1.1 WHAT IS A PROGRAMMING LANGUAGE?

Moving from CS 61A Scheme to CS 61B Java

The countdown problem

VB.NET Programming Fundamentals

CSC Software II: Principles of Programming Languages

1 Introduction. 2 An Interpreter. 2.1 Handling Source Code

History OOP languages Year Language 1967 Simula Smalltalk

Functional Programming in C++11

Chapter 1. Dr. Chris Irwin Davis Phone: (972) Office: ECSS CS-4337 Organization of Programming Languages

Programming Languages

How To Program In Scheme (Prolog)

Concepts of Programming Languages: A Unified Approach. Karl Abrahamson

Announcements FORTRAN ALGOL COBOL. Simula & Smalltalk. Programming Languages

Course Goal CMSC 330: Organization of Programming Languages. Studying Programming Languages. All Languages Are (Kind of) Equivalent.

Programming Languages in Artificial Intelligence

[Refer Slide Time: 05:10]

CSE 130 Programming Language Principles & Paradigms

Principles of Programming Languages Topic: Introduction Professor Louis Steinberg

Advanced compiler construction. General course information. Teacher & assistant. Course goals. Evaluation. Grading scheme. Michel Schinz

Semester Review. CSC 301, Fall 2015

Object Oriented Software Design

1998. (R. Bird and P. Wadler, Introduction to Functional Programming, Prentice

Integrating Formal Models into the Programming Languages Course

Chapter 6: Programming Languages

The Clean programming language. Group 25, Jingui Li, Daren Tuzi

Anatomy of Programming Languages. William R. Cook

POLYTYPIC PROGRAMMING OR: Programming Language Theory is Helpful

by Mario Fusco Monadic

7.1 Our Current Model

Programming Language Rankings. Lecture 15: Type Inference, polymorphism & Type Classes. Top Combined. Tiobe Index. CSC 131! Fall, 2014!

Chapter 13 Computer Programs and Programming Languages. Discovering Computers Your Interactive Guide to the Digital World

Introduction to Software Paradigms & Procedural Programming Paradigm

McGraw-Hill The McGraw-Hill Companies, Inc.,

Object Oriented Software Design

Cedalion A Language Oriented Programming Language (Extended Abstract)

Language Evaluation Criteria. Evaluation Criteria: Readability. Evaluation Criteria: Writability. ICOM 4036 Programming Languages

Name: Class: Date: 9. The compiler ignores all comments they are there strictly for the convenience of anyone reading the program.

programming languages, programming language standards and compiler validation

Programming Languages CIS 443

Testing and Tracing Lazy Functional Programs using QuickCheck and Hat

Languages september 12, 2015 Éric Lévénez < FORTRAN III end-1958 FORTRAN II FORTRAN I october 1956

1 Operational Semantics for While

COMP 356 Programming Language Structures Notes for Chapter 4 of Concepts of Programming Languages Scanning and Parsing

Type Classes with Functional Dependencies

Programming by Contract. Programming by Contract: Motivation. Programming by Contract: Preconditions and Postconditions

KITES TECHNOLOGY COURSE MODULE (C, C++, DS)

Object-Oriented Software Specification in Programming Language Design and Implementation

n Introduction n Art of programming language design n Programming language spectrum n Why study programming languages? n Overview of compilation

1/20/2016 INTRODUCTION

Implementing Programming Languages. Aarne Ranta

ATSBA: Advanced Technologies Supporting Business Areas. Programming with Java. 1 Overview and Introduction

TOWARDS A GREEN PROGRAMMING PARADIGM FOR MOBILE SOFTWARE DEVELOPMENT

Parameter passing in LISP

Software Paradigms (Lesson 1) Introduction & Procedural Programming Paradigm

The Cool Reference Manual

Parameter Passing. Parameter Passing. Parameter Passing Modes in Fortran. Parameter Passing Modes in C

Parsing Technology and its role in Legacy Modernization. A Metaware White Paper

Chapter 5 Names, Bindings, Type Checking, and Scopes

On Understanding Types, Data Abstraction, and Polymorphism

Ed. v1.0 PROGRAMMING LANGUAGES WORKING PAPER DRAFT PROGRAMMING LANGUAGES. Ed. v1.0

Compilers. Introduction to Compilers. Lecture 1. Spring term. Mick O Donnell: michael.odonnell@uam.es Alfonso Ortega: alfonso.ortega@uam.

CS 141: Introduction to (Java) Programming: Exam 1 Jenny Orr Willamette University Fall 2013

CSE 373: Data Structure & Algorithms Lecture 25: Programming Languages. Nicki Dell Spring 2014

The C Programming Language course syllabus associate level

Introduction to Python

Programming Language Concepts for Software Developers

Sources: On the Web: Slides will be available on:

The previous chapter provided a definition of the semantics of a programming

Structure of Presentation. The Role of Programming in Informatics Curricula. Concepts of Informatics 2. Concepts of Informatics 1

The Needle Programming Language

Accentuate the Negative: Homework Examples from ACE

Organization of Programming Languages CS320/520N. Lecture 05. Razvan C. Bunescu School of Electrical Engineering and Computer Science

PART-A Questions. 2. How does an enumerated statement differ from a typedef statement?

Fundamentals of Programming Languages

Computer Programming I & II*

On Understanding Types, Data Abstraction, and Polymorphism

ADVANCED SCHOOL OF SYSTEMS AND DATA STUDIES (ASSDAS) PROGRAM: CTech in Computer Science

THE ROLE OF PROGRAMMING PARADIGMS IN THE FIRST PROGRAMMING COURSES. 1. Introduction

The Java Series. Java Essentials I What is Java? Basic Language Constructs. Java Essentials I. What is Java?. Basic Language Constructs Slide 1

Computer Programming I

Programming Languages

CS 241 Data Organization Coding Standards

Chapter 3. Input and output. 3.1 The System class

Mobile App Design Project #1 Java Boot Camp: Design Model for Chutes and Ladders Board Game

Software Development (CS2500)

C Compiler Targeting the Java Virtual Machine

1 Abstract Data Types Information Hiding

Transcription:

FP 2005 1.1 3 Functional Programming WOLFRAM KAHL kahl@mcmaster.ca Department of Computing and Software McMaster University

FP 2005 1.2 4 What Kinds of Programming Languages are There? Imperative telling the machine what to do Declarative telling the machine what to achieve Programming Languages Imperative Declarative C, Pascal FORTRAN COBOL Modula-2 Object-oriented C++, Oberon-2 Java, Smalltalk Functional Haskell, OCaml ML, Scheme, LISP Logic Prolog Mercury

FP 2005 1.3 5 What Kinds of Programming Languages are There? Imperative telling the machine what to do Declarative telling the machine what to achieve Programming Languages Imperative Declarative C, Pascal FORTRAN COBOL Modula-2 Object-oriented C++, Oberon-2 Java, Smalltalk Functional Haskell, OCaml ML, Scheme, LISP Logic Prolog Mercury

FP 2005 1.4 6 What Kinds of Programming Languages are There? Imperative telling the machine what to do Declarative telling the machine what to achieve Programming Languages Imperative Declarative C, Pascal FORTRAN COBOL Modula-2 Object-oriented C++, Oberon-2 Java, Smalltalk Functional Haskell, OCaml ML, Scheme, LISP Logic Prolog Mercury

FP 2005 1.5 7 What Kinds of Programming Languages are There? Imperative telling the machine what to do Declarative telling the machine what to achieve Programming Languages Imperative Declarative C, Pascal FORTRAN COBOL Modula-2 Object-oriented C++, Oberon-2 Java, Smalltalk Functional Haskell, OCaml ML, Scheme, LISP Logic Prolog Mercury

FP 2005 1.6 8 What Kinds of Programming Languages are There? Imperative telling the machine what to do Declarative telling the machine what to achieve Programming Languages Imperative Declarative C, Pascal FORTRAN COBOL Modula-2 Object-oriented C++, Oberon-2 Java, Smalltalk Functional Haskell, OCaml ML, Scheme, LISP Logic Prolog Mercury

FP 2005 1.7 9 What Kinds of Programming Languages are There? Imperative telling the machine what to do Declarative telling the machine what to achieve Programming Languages Imperative Declarative C, Pascal FORTRAN COBOL Modula-2 Object-oriented C++, Oberon-2 Java, Smalltalk Functional Haskell, OCaml ML, Scheme, LISP Logic Prolog Mercury

FP 2005 1.8 10 What Kinds of Programming Languages are There? Imperative telling the machine what to do Declarative telling the machine what to achieve Programming Languages Imperative Declarative C, Pascal FORTRAN COBOL Modula-2 Object-oriented C++, Oberon-2 Java, Smalltalk Functional Haskell, OCaml ML, Scheme, LISP Logic Prolog Mercury

FP 2005 1.9 11 Programming Language Paradigms Imperative Programming Languages Statement oriented languages Every statement changes the machine state Object-oriented languages Organising the state into objects with individual state and behaviour Message passing paradigm (instead of subprogram call) Rule-Based (Logical) Programming Languages Specify rule that specifies problem solution (Prolog, BNF Parsing) Other examples: Decision procedures, Grammar rules (BNF) Programming consists of specifying the attributes of the answer Functional (Applicative) Programming Languages Goal is to understand the function that produces the answer Function composition is major operation Programming consists of building the function that computes the answer

FP 2005 1.10 12 Historical Development of Programming Languages

FP 2005 1.11 13 Historical Development of Programming Languages Emphasis has changed:

FP 2005 1.12 14 Historical Development of Programming Languages Emphasis has changed: from making life easier for the computer

FP 2005 1.13 15 Historical Development of Programming Languages Emphasis has changed: from making life easier for the computer to making it easier for the programmer.

FP 2005 1.14 16 Historical Development of Programming Languages Emphasis has changed: from making life easier for the computer to making it easier for the programmer. Easier for the programmer means:

FP 2005 1.15 17 Historical Development of Programming Languages Emphasis has changed: from making life easier for the computer to making it easier for the programmer. Easier for the programmer means: Use languages that facilitate writing error-free programs

FP 2005 1.16 18 Historical Development of Programming Languages Emphasis has changed: from making life easier for the computer to making it easier for the programmer. Easier for the programmer means: Use languages that facilitate writing error-free programs Use languages that facilitate writing programs that are easy to maintain

FP 2005 1.17 19 Historical Development of Programming Languages Emphasis has changed: from making life easier for the computer to making it easier for the programmer. Easier for the programmer means: Use languages that facilitate writing error-free programs Use languages that facilitate writing programs that are easy to maintain Goal of language development:

FP 2005 1.18 20 Historical Development of Programming Languages Emphasis has changed: from making life easier for the computer to making it easier for the programmer. Easier for the programmer means: Use languages that facilitate writing error-free programs Use languages that facilitate writing programs that are easy to maintain Goal of language development: Developers concentrate on design (or even just specification) Programming is trivial or handled by computer (executable specification languages, rapid prototyping)

FP 2005 1.19 21 Important Functional Programming Languages Functional Programming Languages pure, statically typed impure Haskell Clean statically typed dynamically typed Standard ML OCaml LISP, Scheme APL, J Erlang

FP 2005 1.20 22 Important Functional Programming Languages Functional Programming Languages pure, statically typed impure Haskell Clean statically typed dynamically typed Standard ML OCaml LISP, Scheme APL, J Erlang

FP 2005 1.21 23 Important Functional Programming Languages Functional Programming Languages pure, statically typed impure Haskell Clean statically typed dynamically typed Standard ML OCaml LISP, Scheme APL, J Erlang

FP 2005 1.22 24 Important Functional Programming Languages Functional Programming Languages pure, statically typed impure Haskell Clean statically typed dynamically typed Standard ML OCaml LISP, Scheme APL, J Erlang

FP 2005 1.23 25 Important Functional Programming Languages Functional Programming Languages pure, statically typed impure Haskell Clean statically typed dynamically typed Standard ML OCaml LISP, Scheme APL, J Erlang

FP 2005 1.24 26 Important Functional Programming Languages Functional Programming Languages pure, statically typed impure Haskell Clean statically typed dynamically typed Standard ML OCaml LISP, Scheme APL, J Erlang

FP 2005 1.25 27 Important Functional Programming Languages Functional Programming Languages pure, statically typed impure Haskell Clean statically typed dynamically typed Standard ML OCaml LISP, Scheme APL, J Erlang

FP 2005 2.1 29 Haskell

FP 2005 2.2 30 Haskell functional

FP 2005 2.3 31 Haskell functional programs are function definitions

FP 2005 2.4 32 Haskell functional programs are function definitions; functions are first-class citizens

FP 2005 2.5 33 Haskell functional programs are function definitions; functions are first-class citizens pure (referentially transparent)

FP 2005 2.6 34 Haskell functional programs are function definitions; functions are first-class citizens pure (referentially transparent) no side-effects

FP 2005 2.7 35 Haskell functional programs are function definitions; functions are first-class citizens pure (referentially transparent) no side-effects non-strict (lazy)

FP 2005 2.8 36 Haskell functional programs are function definitions; functions are first-class citizens pure (referentially transparent) no side-effects non-strict (lazy) arguments are evaluated only when needed

FP 2005 2.9 37 Haskell functional programs are function definitions; functions are first-class citizens pure (referentially transparent) no side-effects non-strict (lazy) arguments are evaluated only when needed statically strongly typed

FP 2005 2.10 38 Haskell functional programs are function definitions; functions are first-class citizens pure (referentially transparent) no side-effects non-strict (lazy) arguments are evaluated only when needed statically strongly typed all type errors caught at compile-time

FP 2005 2.11 39 Haskell functional programs are function definitions; functions are first-class citizens pure (referentially transparent) no side-effects non-strict (lazy) arguments are evaluated only when needed statically strongly typed all type errors caught at compile-time type classes safe overloading

FP 2005 2.12 40 Haskell functional programs are function definitions; functions are first-class citizens pure (referentially transparent) no side-effects non-strict (lazy) arguments are evaluated only when needed statically strongly typed all type errors caught at compile-time type classes safe overloading Standardised language version: Haskell 98

FP 2005 2.13 41 Haskell functional programs are function definitions; functions are first-class citizens pure (referentially transparent) no side-effects non-strict (lazy) arguments are evaluated only when needed statically strongly typed all type errors caught at compile-time type classes safe overloading Standardised language version: Haskell 98 Several compilers and interpreters available

FP 2005 2.14 42 Haskell functional programs are function definitions; functions are first-class citizens pure (referentially transparent) no side-effects non-strict (lazy) arguments are evaluated only when needed statically strongly typed all type errors caught at compile-time type classes safe overloading Standardised language version: Haskell 98 Several compilers and interpreters available Comprehensive web site: http://haskell.org/

FP 2005 2.15 43 Important Points

FP 2005 2.16 44 Important Points Execution of Haskell programs

FP 2005 2.17 45 Important Points Execution of Haskell programs is expression evaluation

FP 2005 2.18 46 Important Points Execution of Haskell programs is expression evaluation (for the time being)

FP 2005 2.19 47 Important Points Execution of Haskell programs is expression evaluation (for the time being) Defining functions in Haskell

FP 2005 2.20 48 Important Points Execution of Haskell programs is expression evaluation (for the time being) Defining functions in Haskell is more like defining functions in mathematics

FP 2005 2.21 49 Important Points Execution of Haskell programs is expression evaluation (for the time being) Defining functions in Haskell is more like defining functions in mathematics than like defining procedures in C or classes and methods in Java

FP 2005 2.22 50 Important Points Execution of Haskell programs is expression evaluation (for the time being) Defining functions in Haskell is more like defining functions in mathematics than like defining procedures in C or classes and methods in Java One Haskell function may be defined by several equations

FP 2005 2.23 51 Important Points Execution of Haskell programs is expression evaluation (for the time being) Defining functions in Haskell is more like defining functions in mathematics than like defining procedures in C or classes and methods in Java One Haskell function may be defined by several equations the first that matches is used

FP 2005 2.24 52 Important Points Execution of Haskell programs is expression evaluation (for the time being) Defining functions in Haskell is more like defining functions in mathematics than like defining procedures in C or classes and methods in Java One Haskell function may be defined by several equations the first that matches is used Lists are an easy-to-use datastructure with lots of language and library support

FP 2005 2.25 53 Important Points Execution of Haskell programs is expression evaluation (for the time being) Defining functions in Haskell is more like defining functions in mathematics than like defining procedures in C or classes and methods in Java One Haskell function may be defined by several equations the first that matches is used Lists are an easy-to-use datastructure with lots of language and library support therefore, lists are heavily used in beginners material.

FP 2005 2.26 54 Important Points Execution of Haskell programs is expression evaluation (for the time being) Defining functions in Haskell is more like defining functions in mathematics than like defining procedures in C or classes and methods in Java One Haskell function may be defined by several equations the first that matches is used Lists are an easy-to-use datastructure with lots of language and library support therefore, lists are heavily used in beginners material. In many cases, advanced Haskell programmers will use other datastructures, for example Sets, or FiniteMaps instead of association lists.

FP 2005 2.27 55 Simple Expression Evaluation The Haskell interpreters hugs, ghci, and hi accept any expression at their prompt and print (after the first ENTER) the value resulting from evaluation of that expression. Prelude> 4*(5+6)-2 42 Expression evaluation proceeds by applying rules to subexpressions: 4*(5+6)-2 = (addition) 4*11-2 (multiplication)

FP 2005 2.28 56 Simple Expression Evaluation The Haskell interpreters hugs, ghci, and hi accept any expression at their prompt and print (after the first ENTER) the value resulting from evaluation of that expression. Prelude> 4*(5+6)-2 42 Expression evaluation proceeds by applying rules to subexpressions: 4*(5+6)-2 [subtraction & mult. impossible] = (addition) 4*11-2 (multiplication)

FP 2005 2.29 57 Simple Expression Evaluation The Haskell interpreters hugs, ghci, and hi accept any expression at their prompt and print (after the first ENTER) the value resulting from evaluation of that expression. Prelude> 4*(5+6)-2 42 Expression evaluation proceeds by applying rules to subexpressions: 4*(5+6)-2 [subtraction & mult. impossible] = (addition) 4*11-2 (multiplication)

FP 2005 2.30 58 Simple Expression Evaluation The Haskell interpreters hugs, ghci, and hi accept any expression at their prompt and print (after the first ENTER) the value resulting from evaluation of that expression. Prelude> 4*(5+6)-2 42 Expression evaluation proceeds by applying rules to subexpressions: 4*(5+6)-2 [subtraction & mult. impossible] = (addition) 4*11-2 [subtraction impossible] (multiplication)

FP 2005 2.31 59 Simple Expression Evaluation The Haskell interpreters hugs, ghci, and hi accept any expression at their prompt and print (after the first ENTER) the value resulting from evaluation of that expression. Prelude> 4*(5+6)-2 42 Expression evaluation proceeds by applying rules to subexpressions: 4*(5+6)-2 [subtraction & mult. impossible] = (addition) 4*11-2 [subtraction impossible] = (multiplication) 44-2

FP 2005 2.32 60 Simple Expression Evaluation The Haskell interpreters hugs, ghci, and hi accept any expression at their prompt and print (after the first ENTER) the value resulting from evaluation of that expression. Prelude> 4*(5+6)-2 42 Expression evaluation proceeds by applying rules to subexpressions: 4*(5+6)-2 [subtraction & mult. impossible] = (addition) 4*11-2 [subtraction impossible] = (multiplication) 44-2 = (subtraction) 42

FP 2005 2.33 61 Simple Expression Evaluation Explanation

FP 2005 2.34 62 Simple Expression Evaluation Explanation Arguments to a fuction or operation are evaluated only when needed.

FP 2005 2.35 63 Simple Expression Evaluation Explanation Arguments to a fuction or operation are evaluated only when needed. If for obtaining a result from an application of a function f to a number of arguments,

FP 2005 2.36 64 Simple Expression Evaluation Explanation Arguments to a fuction or operation are evaluated only when needed. If for obtaining a result from an application of a function f to a number of arguments, the value of the argument at position i is always needed

FP 2005 2.37 65 Simple Expression Evaluation Explanation Arguments to a fuction or operation are evaluated only when needed. If for obtaining a result from an application of a function f to a number of arguments, the value of the argument at position i is always needed. then f is called strict in its i-th argument

FP 2005 2.38 66 Simple Expression Evaluation Explanation Arguments to a fuction or operation are evaluated only when needed. If for obtaining a result from an application of a function f to a number of arguments, the value of the argument at position i is always needed. then f is called strict in its i-th argument Therefore: If f is strict in its i-th argument

FP 2005 2.39 67 Simple Expression Evaluation Explanation Arguments to a fuction or operation are evaluated only when needed. If for obtaining a result from an application of a function f to a number of arguments, the value of the argument at position i is always needed. then f is called strict in its i-th argument Therefore: If f is strict in its i-th argument, then the i-th argument has to be evaluated whenever a result is needed from f.

FP 2005 2.40 68 Simple Expression Evaluation Explanation Arguments to a fuction or operation are evaluated only when needed. If for obtaining a result from an application of a function f to a number of arguments, the value of the argument at position i is always needed. then f is called strict in its i-th argument Therefore: If f is strict in its i-th argument, then the i-th argument has to be evaluated whenever a result is needed from f. Simpler: A one-argument function f is strict iff f undefined = undefined.

FP 2005 2.41 69 Simple Expression Evaluation Explanation Arguments to a fuction or operation are evaluated only when needed. If for obtaining a result from an application of a function f to a number of arguments, the value of the argument at position i is always needed. then f is called strict in its i-th argument Therefore: If f is strict in its i-th argument, then the i-th argument has to be evaluated whenever a result is needed from f. Simpler: A one-argument function f is strict iff Constant functions are non-strict: f undefined = undefined.

FP 2005 2.42 70 Simple Expression Evaluation Explanation Arguments to a fuction or operation are evaluated only when needed. If for obtaining a result from an application of a function f to a number of arguments, the value of the argument at position i is always needed. then f is called strict in its i-th argument Therefore: If f is strict in its i-th argument, then the i-th argument has to be evaluated whenever a result is needed from f. Simpler: A one-argument function f is strict iff f undefined = undefined. Constant functions are non-strict: ( const 5) undefined = 5

FP 2005 2.43 71 Simple Expression Evaluation Explanation Arguments to a fuction or operation are evaluated only when needed. If for obtaining a result from an application of a function f to a number of arguments, the value of the argument at position i is always needed. then f is called strict in its i-th argument Therefore: If f is strict in its i-th argument, then the i-th argument has to be evaluated whenever a result is needed from f. Simpler: A one-argument function f is strict iff f undefined = undefined. Constant functions are non-strict: ( const 5) undefined = 5 Checking a list for emptyness is strict:

FP 2005 2.44 72 Simple Expression Evaluation Explanation Arguments to a fuction or operation are evaluated only when needed. If for obtaining a result from an application of a function f to a number of arguments, the value of the argument at position i is always needed. then f is called strict in its i-th argument Therefore: If f is strict in its i-th argument, then the i-th argument has to be evaluated whenever a result is needed from f. Simpler: A one-argument function f is strict iff f undefined = undefined. Constant functions are non-strict: ( const 5) undefined = 5 Checking a list for emptyness is strict: null undefined = undefined

FP 2005 2.45 73 Simple Expression Evaluation Explanation Arguments to a fuction or operation are evaluated only when needed. If for obtaining a result from an application of a function f to a number of arguments, the value of the argument at position i is always needed. then f is called strict in its i-th argument Therefore: If f is strict in its i-th argument, then the i-th argument has to be evaluated whenever a result is needed from f. Simpler: A one-argument function f is strict iff f undefined = undefined. Constant functions are non-strict: ( const 5) undefined = 5 Checking a list for emptyness is strict: null undefined = undefined List construction is non-strict:

FP 2005 2.46 74 Simple Expression Evaluation Explanation Arguments to a fuction or operation are evaluated only when needed. If for obtaining a result from an application of a function f to a number of arguments, the value of the argument at position i is always needed. then f is called strict in its i-th argument Therefore: If f is strict in its i-th argument, then the i-th argument has to be evaluated whenever a result is needed from f. Simpler: A one-argument function f is strict iff f undefined = undefined. Constant functions are non-strict: ( const 5) undefined = 5 Checking a list for emptyness is strict: null undefined = undefined List construction is non-strict: null ( undefined : undefined ) = False

FP 2005 2.47 75 Simple Expression Evaluation Explanation Arguments to a fuction or operation are evaluated only when needed. If for obtaining a result from an application of a function f to a number of arguments, the value of the argument at position i is always needed. then f is called strict in its i-th argument Therefore: If f is strict in its i-th argument, then the i-th argument has to be evaluated whenever a result is needed from f. Simpler: A one-argument function f is strict iff f undefined = undefined. Constant functions are non-strict: ( const 5) undefined = 5 Checking a list for emptyness is strict: null undefined = undefined List construction is non-strict: null ( undefined : undefined ) = False Standard arithmetic operators are strict in both arguments:

FP 2005 2.48 76 Simple Expression Evaluation Explanation Arguments to a fuction or operation are evaluated only when needed. If for obtaining a result from an application of a function f to a number of arguments, the value of the argument at position i is always needed. then f is called strict in its i-th argument Therefore: If f is strict in its i-th argument, then the i-th argument has to be evaluated whenever a result is needed from f. Simpler: A one-argument function f is strict iff f undefined = undefined. Constant functions are non-strict: ( const 5) undefined = 5 Checking a list for emptyness is strict: null undefined = undefined List construction is non-strict: null ( undefined : undefined ) = False Standard arithmetic operators are strict in both arguments: 0 undefined = undefined

FP 2005 2.49 77 Unfolding Definitions Assume the following definitions to be in scope: answer = 42 magic = 7 Expression evaluation will unfold (or expand) definitions: Prelude> (answer - 1) * (magic * answer - 23) 11111

FP 2005 2.50 78 Unfolding Definitions Assume the following definitions to be in scope: answer = 42 magic = 7 Expression evaluation will unfold (or expand) definitions: Prelude> (answer - 1) * (magic * answer - 23) 11111 (answer - 1) * (magic * answer - 23)

FP 2005 2.51 79 Unfolding Definitions Assume the following definitions to be in scope: answer = 42 magic = 7 Expression evaluation will unfold (or expand) definitions: Prelude> (answer - 1) * (magic * answer - 23) 11111 (answer - 1) * (magic * answer - 23) = (42-1) * (magic * 42-23) (answer)

FP 2005 2.52 80 Unfolding Definitions Assume the following definitions to be in scope: answer = 42 magic = 7 Expression evaluation will unfold (or expand) definitions: Prelude> (answer - 1) * (magic * answer - 23) 11111 (answer - 1) * (magic * answer - 23) = (42-1) * (magic * 42-23) (answer) = 41 * (magic * 42-23) (subtraction)

FP 2005 2.53 81 Unfolding Definitions Assume the following definitions to be in scope: answer = 42 magic = 7 Expression evaluation will unfold (or expand) definitions: Prelude> (answer - 1) * (magic * answer - 23) 11111 (answer - 1) * (magic * answer - 23) = (42-1) * (magic * 42-23) (answer) = 41 * (magic * 42-23) (subtraction) = 41 * (7 * 42-23) (magic)

FP 2005 2.54 82 Unfolding Definitions Assume the following definitions to be in scope: answer = 42 magic = 7 Expression evaluation will unfold (or expand) definitions: Prelude> (answer - 1) * (magic * answer - 23) 11111 (answer - 1) * (magic * answer - 23) = (42-1) * (magic * 42-23) (answer) = 41 * (magic * 42-23) (subtraction) = 41 * (7 * 42-23) (magic) = 41 * (294-23) (multiplication)

FP 2005 2.55 83 Unfolding Definitions Assume the following definitions to be in scope: answer = 42 magic = 7 Expression evaluation will unfold (or expand) definitions: Prelude> (answer - 1) * (magic * answer - 23) 11111 (answer - 1) * (magic * answer - 23) = (42-1) * (magic * 42-23) (answer) = 41 * (magic * 42-23) (subtraction) = 41 * (7 * 42-23) (magic) = 41 * (294-23) (multiplication) = 41 * 271 (subtraction)

FP 2005 2.56 84 Unfolding Definitions Assume the following definitions to be in scope: answer = 42 magic = 7 Expression evaluation will unfold (or expand) definitions: Prelude> (answer - 1) * (magic * answer - 23) 11111 (answer - 1) * (magic * answer - 23) = (42-1) * (magic * 42-23) (answer) = 41 * (magic * 42-23) (subtraction) = 41 * (7 * 42-23) (magic) = 41 * (294-23) (multiplication) = 41 * 271 (subtraction) = 11111 (multiplication)

FP 2005 2.57 85 Easy! How did I find those numbers? Prelude> [ n n <- [1.. 400], 11111 mod n == 0 ] [1,41,271] This is a list comprehension: return all n where n is taken from then list [1.. 400] and a result is returned only if n divides 11111.

FP 2005 2.58 86 Conditional Expressions Prelude> if 11111 mod 41 == 0 then 11111 div 41 else 5 271 The pattern is: if condition then expression1 else expression2 If the condition evaluates to True, the conditional expression evaluates to the value of expression1. If the condition evaluates to False, the conditional expression evaluates to the value of expression2.

FP 2005 2.59 87 Conditional Expressions Prelude> if 11111 mod 41 == 0 then 11111 div 41 else 5 271 The pattern is: if condition then expression1 else expression2 If the condition evaluates to True, the conditional expression evaluates to the value of expression1. If the condition evaluates to False, the conditional expression evaluates to the value of expression2. Therefore: if _ then _ else is strict in the condition.

FP 2005 2.60 88 Conditional Expressions Prelude> if 11111 mod 41 == 0 then 11111 div 41 else 5 271 The pattern is: if condition then expression1 else expression2 If the condition evaluates to True, the conditional expression evaluates to the value of expression1. If the condition evaluates to False, the conditional expression evaluates to the value of expression2. Therefore: if _ then _ else is strict in the condition. In C: ( condition? expression1 : expression2 )

FP 2005 2.61 89 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1)

FP 2005 2.62 90 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3

FP 2005 2.63 91 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1)

FP 2005 2.64 92 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1) = if False then 1 else 3 * fact (3-1)

FP 2005 2.65 93 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1) = if False then 1 else 3 * fact (3-1) = 3 * fact (3-1)

FP 2005 2.66 94 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1) = if False then 1 else 3 * fact (3-1) = 3 * fact (3-1) = 3 * if (3-1) == 0 then 1 else (3-1) * fact ((3-1)-1)

FP 2005 2.67 95 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1) = if False then 1 else 3 * fact (3-1) = 3 * fact (3-1) = 3 * if (3-1) == 0 then 1 else (3-1) * fact ((3-1)-1) = 3 * if 2 == 0 then 1 else 2 * fact (2-1)

FP 2005 2.68 96 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1) = if False then 1 else 3 * fact (3-1) = 3 * fact (3-1) = 3 * if (3-1) == 0 then 1 else (3-1) * fact ((3-1)-1) = 3 * if 2 == 0 then 1 else 2 * fact (2-1) = 3 * if False then 1 else 2 * fact (2-1)

FP 2005 2.69 97 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1) = if False then 1 else 3 * fact (3-1) = 3 * fact (3-1) = 3 * if (3-1) == 0 then 1 else (3-1) * fact ((3-1)-1) = 3 * if 2 == 0 then 1 else 2 * fact (2-1) = 3 * if False then 1 else 2 * fact (2-1) = 3 * 2 * fact (2-1)

FP 2005 2.70 98 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1) = if False then 1 else 3 * fact (3-1) = 3 * fact (3-1) = 3 * if (3-1) == 0 then 1 else (3-1) * fact ((3-1)-1) = 3 * if 2 == 0 then 1 else 2 * fact (2-1) = 3 * if False then 1 else 2 * fact (2-1) = 3 * 2 * fact (2-1) = 3 * 2 * if (2-1) == 0 then 1 else (2-1) * fact ((2-1)-1)

FP 2005 2.71 99 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1) = if False then 1 else 3 * fact (3-1) = 3 * fact (3-1) = 3 * if (3-1) == 0 then 1 else (3-1) * fact ((3-1)-1) = 3 * if 2 == 0 then 1 else 2 * fact (2-1) = 3 * if False then 1 else 2 * fact (2-1) = 3 * 2 * fact (2-1) = 3 * 2 * if (2-1) == 0 then 1 else (2-1) * fact ((2-1)-1) = 3 * 2 * if 1 == 0 then 1 else 1 * fact (1-1)

FP 2005 2.72 100 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1) = if False then 1 else 3 * fact (3-1) = 3 * fact (3-1) = 3 * if (3-1) == 0 then 1 else (3-1) * fact ((3-1)-1) = 3 * if 2 == 0 then 1 else 2 * fact (2-1) = 3 * if False then 1 else 2 * fact (2-1) = 3 * 2 * fact (2-1) = 3 * 2 * if (2-1) == 0 then 1 else (2-1) * fact ((2-1)-1) = 3 * 2 * if 1 == 0 then 1 else 1 * fact (1-1) = 3 * 2 * if False then 1 else 1 * fact (1-1)

FP 2005 2.73 101 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1) = if False then 1 else 3 * fact (3-1) = 3 * fact (3-1) = 3 * if (3-1) == 0 then 1 else (3-1) * fact ((3-1)-1) = 3 * if 2 == 0 then 1 else 2 * fact (2-1) = 3 * if False then 1 else 2 * fact (2-1) = 3 * 2 * fact (2-1) = 3 * 2 * if (2-1) == 0 then 1 else (2-1) * fact ((2-1)-1) = 3 * 2 * if 1 == 0 then 1 else 1 * fact (1-1) = 3 * 2 * if False then 1 else 1 * fact (1-1) = 3 * 2 * 1 * fact (1-1)

FP 2005 2.74 102 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1) = if False then 1 else 3 * fact (3-1) = 3 * fact (3-1) = 3 * if (3-1) == 0 then 1 else (3-1) * fact ((3-1)-1) = 3 * if 2 == 0 then 1 else 2 * fact (2-1) = 3 * if False then 1 else 2 * fact (2-1) = 3 * 2 * fact (2-1) = 3 * 2 * if (2-1) == 0 then 1 else (2-1) * fact ((2-1)-1) = 3 * 2 * if 1 == 0 then 1 else 1 * fact (1-1) = 3 * 2 * if False then 1 else 1 * fact (1-1) = 3 * 2 * 1 * fact (1-1) = 3 * 2 * 1 * if (1-1) == 0 then 1 else (1-1) * fact ((1-1)-1)

FP 2005 2.75 103 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1) = if False then 1 else 3 * fact (3-1) = 3 * fact (3-1) = 3 * if (3-1) == 0 then 1 else (3-1) * fact ((3-1)-1) = 3 * if 2 == 0 then 1 else 2 * fact (2-1) = 3 * if False then 1 else 2 * fact (2-1) = 3 * 2 * fact (2-1) = 3 * 2 * if (2-1) == 0 then 1 else (2-1) * fact ((2-1)-1) = 3 * 2 * if 1 == 0 then 1 else 1 * fact (1-1) = 3 * 2 * if False then 1 else 1 * fact (1-1) = 3 * 2 * 1 * fact (1-1) = 3 * 2 * 1 * if (1-1) == 0 then 1 else (1-1) * fact ((1-1)-1) = 3 * 2 * 1 * if 0 == 0 then 1 else 0 * fact (0-1)

FP 2005 2.76 104 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1) = if False then 1 else 3 * fact (3-1) = 3 * fact (3-1) = 3 * if (3-1) == 0 then 1 else (3-1) * fact ((3-1)-1) = 3 * if 2 == 0 then 1 else 2 * fact (2-1) = 3 * if False then 1 else 2 * fact (2-1) = 3 * 2 * fact (2-1) = 3 * 2 * if (2-1) == 0 then 1 else (2-1) * fact ((2-1)-1) = 3 * 2 * if 1 == 0 then 1 else 1 * fact (1-1) = 3 * 2 * if False then 1 else 1 * fact (1-1) = 3 * 2 * 1 * fact (1-1) = 3 * 2 * 1 * if (1-1) == 0 then 1 else (1-1) * fact ((1-1)-1) = 3 * 2 * 1 * if 0 == 0 then 1 else 0 * fact (0-1) = 3 * 2 * 1 * if True then 1 else 0 * fact (0-1)

FP 2005 2.77 105 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1) = if False then 1 else 3 * fact (3-1) = 3 * fact (3-1) = 3 * if (3-1) == 0 then 1 else (3-1) * fact ((3-1)-1) = 3 * if 2 == 0 then 1 else 2 * fact (2-1) = 3 * if False then 1 else 2 * fact (2-1) = 3 * 2 * fact (2-1) = 3 * 2 * if (2-1) == 0 then 1 else (2-1) * fact ((2-1)-1) = 3 * 2 * if 1 == 0 then 1 else 1 * fact (1-1) = 3 * 2 * if False then 1 else 1 * fact (1-1) = 3 * 2 * 1 * fact (1-1) = 3 * 2 * 1 * if (1-1) == 0 then 1 else (1-1) * fact ((1-1)-1) = 3 * 2 * 1 * if 0 == 0 then 1 else 0 * fact (0-1) = 3 * 2 * 1 * if True then 1 else 0 * fact (0-1) = 3 * 2 * 1 * 1

FP 2005 2.78 106 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1) = if False then 1 else 3 * fact (3-1) = 3 * fact (3-1) = 3 * if (3-1) == 0 then 1 else (3-1) * fact ((3-1)-1) = 3 * if 2 == 0 then 1 else 2 * fact (2-1) = 3 * if False then 1 else 2 * fact (2-1) = 3 * 2 * fact (2-1) = 3 * 2 * if (2-1) == 0 then 1 else (2-1) * fact ((2-1)-1) = 3 * 2 * if 1 == 0 then 1 else 1 * fact (1-1) = 3 * 2 * if False then 1 else 1 * fact (1-1) = 3 * 2 * 1 * fact (1-1) = 3 * 2 * 1 * if (1-1) == 0 then 1 else (1-1) * fact ((1-1)-1) = 3 * 2 * 1 * if 0 == 0 then 1 else 0 * fact (0-1) = 3 * 2 * 1 * if True then 1 else 0 * fact (0-1) = 3 * 2 * 1 * 1 = 3 * 2 * 1

FP 2005 2.79 107 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1) = if False then 1 else 3 * fact (3-1) = 3 * fact (3-1) = 3 * if (3-1) == 0 then 1 else (3-1) * fact ((3-1)-1) = 3 * if 2 == 0 then 1 else 2 * fact (2-1) = 3 * if False then 1 else 2 * fact (2-1) = 3 * 2 * fact (2-1) = 3 * 2 * if (2-1) == 0 then 1 else (2-1) * fact ((2-1)-1) = 3 * 2 * if 1 == 0 then 1 else 1 * fact (1-1) = 3 * 2 * if False then 1 else 1 * fact (1-1) = 3 * 2 * 1 * fact (1-1) = 3 * 2 * 1 * if (1-1) == 0 then 1 else (1-1) * fact ((1-1)-1) = 3 * 2 * 1 * if 0 == 0 then 1 else 0 * fact (0-1) = 3 * 2 * 1 * if True then 1 else 0 * fact (0-1) = 3 * 2 * 1 * 1 = 3 * 2 * 1 = 3 * 2

FP 2005 2.80 108 Expanding Function Definitions fact :: Integer -> Integer fact n = if n == 0 then 1 else n * fact (n-1) fact 3 = if 3 == 0 then 1 else 3 * fact (3-1) = if False then 1 else 3 * fact (3-1) = 3 * fact (3-1) = 3 * if (3-1) == 0 then 1 else (3-1) * fact ((3-1)-1) = 3 * if 2 == 0 then 1 else 2 * fact (2-1) = 3 * if False then 1 else 2 * fact (2-1) = 3 * 2 * fact (2-1) = 3 * 2 * if (2-1) == 0 then 1 else (2-1) * fact ((2-1)-1) = 3 * 2 * if 1 == 0 then 1 else 1 * fact (1-1) = 3 * 2 * if False then 1 else 1 * fact (1-1) = 3 * 2 * 1 * fact (1-1) = 3 * 2 * 1 * if (1-1) == 0 then 1 else (1-1) * fact ((1-1)-1) = 3 * 2 * 1 * if 0 == 0 then 1 else 0 * fact (0-1) = 3 * 2 * 1 * if True then 1 else 0 * fact (0-1) = 3 * 2 * 1 * 1 = 3 * 2 * 1 = 3 * 2 = 6

FP 2005 2.81 109 fact :: Integer -> Integer fact 0 = 1 fact n = n * fact (n-1) Matching Function Definitions

FP 2005 2.82 110 fact :: Integer -> Integer fact 0 = 1 fact n = n * fact (n-1) Matching Function Definitions fact 3 = 3 * (2 * (1 * fact (1-1)))

FP 2005 2.83 111 fact :: Integer -> Integer fact 0 = 1 fact n = n * fact (n-1) Matching Function Definitions fact 3 = 3 * fact (3-1) (fact n) = 3 * (2 * (1 * fact (1-1)))

FP 2005 2.84 112 fact :: Integer -> Integer fact 0 = 1 fact n = n * fact (n-1) Matching Function Definitions fact 3 = 3 * fact (3-1) (fact n) = 3 * fact 2 (determining which fact rule matches) = 3 * (2 * (1 * fact (1-1)))

FP 2005 2.85 113 fact :: Integer -> Integer fact 0 = 1 fact n = n * fact (n-1) Matching Function Definitions fact 3 = 3 * fact (3-1) (fact n) = 3 * fact 2 (determining which fact rule matches) = 3 * (2 * fact (2-1)) (fact n) = 3 * (2 * (1 * fact (1-1)))

FP 2005 2.86 114 fact :: Integer -> Integer fact 0 = 1 fact n = n * fact (n-1) Matching Function Definitions fact 3 = 3 * fact (3-1) (fact n) = 3 * fact 2 (determining which fact rule matches) = 3 * (2 * fact (2-1)) (fact n) = 3 * (2 * fact 1) (determining which fact rule matches) = 3 * (2 * (1 * fact (1-1)))

FP 2005 2.87 115 fact :: Integer -> Integer fact 0 = 1 fact n = n * fact (n-1) Matching Function Definitions fact 3 = 3 * fact (3-1) (fact n) = 3 * fact 2 (determining which fact rule matches) = 3 * (2 * fact (2-1)) (fact n) = 3 * (2 * fact 1) (determining which fact rule matches) = 3 * (2 * (1 * fact (1-1))) (fact n)

FP 2005 2.88 116 fact :: Integer -> Integer fact 0 = 1 fact n = n * fact (n-1) Matching Function Definitions fact 3 = 3 * fact (3-1) (fact n) = 3 * fact 2 (determining which fact rule matches) = 3 * (2 * fact (2-1)) (fact n) = 3 * (2 * fact 1) (determining which fact rule matches) = 3 * (2 * (1 * fact (1-1))) (fact n) = 3 * (2 * (1 * fact 0)) (determining which fact rule matches)

FP 2005 2.89 117 fact :: Integer -> Integer fact 0 = 1 fact n = n * fact (n-1) Matching Function Definitions fact 3 = 3 * fact (3-1) (fact n) = 3 * fact 2 (determining which fact rule matches) = 3 * (2 * fact (2-1)) (fact n) = 3 * (2 * fact 1) (determining which fact rule matches) = 3 * (2 * (1 * fact (1-1))) (fact n) = 3 * (2 * (1 * fact 0)) (determining which fact rule matches) = 3 * (2 * (1 * 1)) (fact 0)

FP 2005 2.90 118 fact :: Integer -> Integer fact 0 = 1 fact n = n * fact (n-1) Matching Function Definitions fact 3 = 3 * fact (3-1) (fact n) = 3 * fact 2 (determining which fact rule matches) = 3 * (2 * fact (2-1)) (fact n) = 3 * (2 * fact 1) (determining which fact rule matches) = 3 * (2 * (1 * fact (1-1))) (fact n) = 3 * (2 * (1 * fact 0)) (determining which fact rule matches) = 3 * (2 * (1 * 1)) (fact 0) = 3 * (2 * 1) (multiplication)

FP 2005 2.91 119 fact :: Integer -> Integer fact 0 = 1 fact n = n * fact (n-1) Matching Function Definitions fact 3 = 3 * fact (3-1) (fact n) = 3 * fact 2 (determining which fact rule matches) = 3 * (2 * fact (2-1)) (fact n) = 3 * (2 * fact 1) (determining which fact rule matches) = 3 * (2 * (1 * fact (1-1))) (fact n) = 3 * (2 * (1 * fact 0)) (determining which fact rule matches) = 3 * (2 * (1 * 1)) (fact 0) = 3 * (2 * 1) (multiplication) = 3 * 2 (multiplication)

FP 2005 2.92 120 fact :: Integer -> Integer fact 0 = 1 fact n = n * fact (n-1) Matching Function Definitions fact 3 = 3 * fact (3-1) (fact n) = 3 * fact 2 (determining which fact rule matches) = 3 * (2 * fact (2-1)) (fact n) = 3 * (2 * fact 1) (determining which fact rule matches) = 3 * (2 * (1 * fact (1-1))) (fact n) = 3 * (2 * (1 * fact 0)) (determining which fact rule matches) = 3 * (2 * (1 * 1)) (fact 0) = 3 * (2 * 1) (multiplication) = 3 * 2 (multiplication) = 6 (multiplication)

FP 2005 2.93 121 Lists List display: between square brackets explicitly listing all elements, separated by commas: [1,4,9,16,25]

FP 2005 2.94 122 Lists List display: between square brackets explicitly listing all elements, separated by commas: [1,4,9,16,25] Enumeration lists: denoted by ellipsis.. inside square brackets; defined by beginning (and end, if applicable): [1.. 10] = [1,2,3,4,5,6,7,8,9,10] [1,3.. 10] = [1,3,5,7,9] [1,3.. 11] = [1,3,5,7,9,11] [11,9.. 1] = [11,9,7,5,3,1] [11.. 1] = [] [1.. ] = [1,2,3,4,5,6,7,8,9,10, ] -- infinite list [1,3.. ] = [1,3,5,7,9,11, ] -- infinite list

FP 2005 2.95 123 List Construction

FP 2005 2.96 124 List Construction Display and enumeration lists are syntactic sugar

FP 2005 2.97 125 List Construction Display and enumeration lists are syntactic sugar: A list is

FP 2005 2.98 126 List Construction Display and enumeration lists are syntactic sugar: A list is either the empty list: [], or non-empty

FP 2005 2.99 127 List Construction Display and enumeration lists are syntactic sugar: A list is either the empty list: [], or non-empty, and constructed from a head x and a tail xs

FP 2005 2.100 128 List Construction Display and enumeration lists are syntactic sugar: A list is either the empty list: [], or non-empty, and constructed from a head x and a tail xs (read: xes )

FP 2005 2.101 129 List Construction Display and enumeration lists are syntactic sugar: A list is either the empty list: [], or non-empty, and constructed from a head x and a tail xs (read: xes ) x : xs read: x cons xes.

FP 2005 2.102 130 List Construction Display and enumeration lists are syntactic sugar: A list is either the empty list: [], or non-empty, and constructed from a head x and a tail xs (read: xes ) x : xs read: x cons xes. : is used as infix list constructor:

FP 2005 2.103 131 List Construction Display and enumeration lists are syntactic sugar: A list is either the empty list: [], or non-empty, and constructed from a head x and a tail xs (read: xes ) x : xs read: x cons xes. : is used as infix list constructor: 3 : []

FP 2005 2.104 132 List Construction Display and enumeration lists are syntactic sugar: A list is either the empty list: [], or non-empty, and constructed from a head x and a tail xs (read: xes ) x : xs read: x cons xes. : is used as infix list constructor: 3 : [] = [3]

FP 2005 2.105 133 List Construction Display and enumeration lists are syntactic sugar: A list is either the empty list: [], or non-empty, and constructed from a head x and a tail xs (read: xes ) x : xs read: x cons xes. : is used as infix list constructor: 3 : [] = [3] 2 : [3]

FP 2005 2.106 134 List Construction Display and enumeration lists are syntactic sugar: A list is either the empty list: [], or non-empty, and constructed from a head x and a tail xs (read: xes ) x : xs read: x cons xes. : is used as infix list constructor: 3 : [] = [3] 2 : [3] = [2, 3]

FP 2005 2.107 135 List Construction Display and enumeration lists are syntactic sugar: A list is either the empty list: [], or non-empty, and constructed from a head x and a tail xs (read: xes ) x : xs read: x cons xes. : is used as infix list constructor: 3 : [] = [3] 2 : [3] = [2, 3] 1 : [2, 3]

FP 2005 2.108 136 List Construction Display and enumeration lists are syntactic sugar: A list is either the empty list: [], or non-empty, and constructed from a head x and a tail xs (read: xes ) x : xs read: x cons xes. : is used as infix list constructor: 3 : [] = [3] 2 : [3] = [2, 3] 1 : [2, 3] = [1, 2, 3]

FP 2005 2.109 137 List Construction Display and enumeration lists are syntactic sugar: A list is either the empty list: [], or non-empty, and constructed from a head x and a tail xs (read: xes ) x : xs read: x cons xes. : is used as infix list constructor: 3 : [] = [3] 2 : [3] = [2, 3] 1 : [2, 3] = [1, 2, 3] As an infix operator, : associates to the right

FP 2005 2.110 138 List Construction Display and enumeration lists are syntactic sugar: A list is either the empty list: [], or non-empty, and constructed from a head x and a tail xs (read: xes ) x : xs read: x cons xes. : is used as infix list constructor: 3 : [] = [3] 2 : [3] = [2, 3] 1 : [2, 3] = [1, 2, 3] As an infix operator, : associates to the right: x : y : ys = x : ( y : ys )

FP 2005 2.111 139 List Construction Display and enumeration lists are syntactic sugar: A list is either the empty list: [], or non-empty, and constructed from a head x and a tail xs (read: xes ) x : xs read: x cons xes. : is used as infix list constructor: 3 : [] = [3] 2 : [3] = [2, 3] 1 : [2, 3] = [1, 2, 3] As an infix operator, : associates to the right: Example: 1 : 2 : [3,4] x : y : ys = x : ( y : ys )

FP 2005 2.112 140 List Construction Display and enumeration lists are syntactic sugar: A list is either the empty list: [], or non-empty, and constructed from a head x and a tail xs (read: xes ) x : xs read: x cons xes. : is used as infix list constructor: 3 : [] = [3] 2 : [3] = [2, 3] 1 : [2, 3] = [1, 2, 3] As an infix operator, : associates to the right: Example: 1 : 2 : [3,4] = 1 : (2 : [3, 4]) x : y : ys = x : ( y : ys )

FP 2005 2.113 141 List Construction Display and enumeration lists are syntactic sugar: A list is either the empty list: [], or non-empty, and constructed from a head x and a tail xs (read: xes ) x : xs read: x cons xes. : is used as infix list constructor: 3 : [] = [3] 2 : [3] = [2, 3] 1 : [2, 3] = [1, 2, 3] As an infix operator, : associates to the right: Example: x : y : ys = x : ( y : ys ) 1 : 2 : [3,4] = 1 : (2 : [3, 4]) = 1 : [2, 3, 4]

FP 2005 2.114 142 List Construction Display and enumeration lists are syntactic sugar: A list is either the empty list: [], or non-empty, and constructed from a head x and a tail xs (read: xes ) x : xs read: x cons xes. : is used as infix list constructor: 3 : [] = [3] 2 : [3] = [2, 3] 1 : [2, 3] = [1, 2, 3] As an infix operator, : associates to the right: Example: x : y : ys = x : ( y : ys ) 1 : 2 : [3,4] = 1 : (2 : [3, 4]) = 1 : [2, 3, 4] = [1, 2, 3, 4]

FP 2005 2.115 143 Cons is Not Associative

FP 2005 2.116 144 Cons is Not Associative The convention that : associates to the right allows to save parentheses in certain cirtcumstances.

FP 2005 2.117 145 Cons is Not Associative The convention that : associates to the right allows to save parentheses in certain cirtcumstances. However, : is not associative:

FP 2005 2.118 146 Cons is Not Associative The convention that : associates to the right allows to save parentheses in certain cirtcumstances. However, : is not associative: A list of integers: 1 : (2 : [3,4])

FP 2005 2.119 147 Cons is Not Associative The convention that : associates to the right allows to save parentheses in certain cirtcumstances. However, : is not associative: A list of integers: 1 : (2 : [3,4]) = 1 : 2 : [3,4]

FP 2005 2.120 148 Cons is Not Associative The convention that : associates to the right allows to save parentheses in certain cirtcumstances. However, : is not associative: A list of integers: 1 : (2 : [3,4]) = 1 : 2 : [3,4] = [1, 2, 3, 4]

FP 2005 2.121 149 Cons is Not Associative The convention that : associates to the right allows to save parentheses in certain cirtcumstances. However, : is not associative: A list of integers: 1 : (2 : [3,4]) = 1 : 2 : [3,4] = [1, 2, 3, 4] (1 : 2) : [3,4]

FP 2005 2.122 150 Cons is Not Associative The convention that : associates to the right allows to save parentheses in certain cirtcumstances. However, : is not associative: A list of integers: 1 : (2 : [3,4]) = 1 : 2 : [3,4] = [1, 2, 3, 4] (1 : 2) : [3,4] is nonsense

FP 2005 2.123 151 Cons is Not Associative The convention that : associates to the right allows to save parentheses in certain cirtcumstances. However, : is not associative: A list of integers: 1 : (2 : [3,4]) = 1 : 2 : [3,4] = [1, 2, 3, 4] (1 : 2) : [3,4] is nonsense, since 2 is not a list!

FP 2005 2.124 152 Cons is Not Associative The convention that : associates to the right allows to save parentheses in certain cirtcumstances. However, : is not associative: A list of integers: 1 : (2 : [3,4]) = 1 : 2 : [3,4] = [1, 2, 3, 4] (1 : 2) : [3,4] is nonsense, since 2 is not a list! A list of lists of integers: [2] : [[3,4,5], [6,7]]

FP 2005 2.125 153 Cons is Not Associative The convention that : associates to the right allows to save parentheses in certain cirtcumstances. However, : is not associative: A list of integers: 1 : (2 : [3,4]) = 1 : 2 : [3,4] = [1, 2, 3, 4] (1 : 2) : [3,4] is nonsense, since 2 is not a list! A list of lists of integers: [2] : [[3,4,5], [6,7]] = [[2],[3,4,5],[6,7]]

FP 2005 2.126 154 Cons is Not Associative The convention that : associates to the right allows to save parentheses in certain cirtcumstances. However, : is not associative: A list of integers: 1 : (2 : [3,4]) = 1 : 2 : [3,4] = [1, 2, 3, 4] (1 : 2) : [3,4] is nonsense, since 2 is not a list! A list of lists of integers: [2] : [[3,4,5], [6,7]] = [[2],[3,4,5],[6,7]] Another list of lists of integers: (1 : [2]) : [[3,4,5], [6,7]]

FP 2005 2.127 155 Cons is Not Associative The convention that : associates to the right allows to save parentheses in certain cirtcumstances. However, : is not associative: A list of integers: 1 : (2 : [3,4]) = 1 : 2 : [3,4] = [1, 2, 3, 4] (1 : 2) : [3,4] is nonsense, since 2 is not a list! A list of lists of integers: [2] : [[3,4,5], [6,7]] = [[2],[3,4,5],[6,7]] Another list of lists of integers: (1 : [2]) : [[3,4,5], [6,7]] = [[1,2],[3,4,5],[6,7]]

FP 2005 2.128 156 Cons is Not Associative The convention that : associates to the right allows to save parentheses in certain cirtcumstances. However, : is not associative: A list of integers: 1 : (2 : [3,4]) = 1 : 2 : [3,4] = [1, 2, 3, 4] (1 : 2) : [3,4] is nonsense, since 2 is not a list! A list of lists of integers: [2] : [[3,4,5], [6,7]] = [[2],[3,4,5],[6,7]] Another list of lists of integers: (1 : [2]) : [[3,4,5], [6,7]] = [[1,2],[3,4,5],[6,7]] 1 : ([2] : [[3,4,5], [6,7]])

FP 2005 2.129 157 Cons is Not Associative The convention that : associates to the right allows to save parentheses in certain cirtcumstances. However, : is not associative: A list of integers: 1 : (2 : [3,4]) = 1 : 2 : [3,4] = [1, 2, 3, 4] (1 : 2) : [3,4] is nonsense, since 2 is not a list! A list of lists of integers: [2] : [[3,4,5], [6,7]] = [[2],[3,4,5],[6,7]] Another list of lists of integers: (1 : [2]) : [[3,4,5], [6,7]] = [[1,2],[3,4,5],[6,7]] 1 : ([2] : [[3,4,5], [6,7]]) is nonsense again!

FP 2005 2.130 158 Cons is Not Associative The convention that : associates to the right allows to save parentheses in certain cirtcumstances. However, : is not associative: A list of integers: 1 : (2 : [3,4]) = 1 : 2 : [3,4] = [1, 2, 3, 4] (1 : 2) : [3,4] is nonsense, since 2 is not a list! A list of lists of integers: [2] : [[3,4,5], [6,7]] = [[2],[3,4,5],[6,7]] Another list of lists of integers: (1 : [2]) : [[3,4,5], [6,7]] = [[1,2],[3,4,5],[6,7]] 1 : ([2] : [[3,4,5], [6,7]]) is nonsense again! Reason: 1 and [2] cannot be members of the same list (type error).

FP 2005 2.131 159 List Comprehensions General shape: [ term generator {, generator_or_constraint } ]

FP 2005 2.132 160 General shape: Examples: [ n n n [1.. 5] ] List Comprehensions [ term generator {, generator_or_constraint } ]

FP 2005 2.133 161 List Comprehensions General shape: [ term generator {, generator_or_constraint } ] Examples: [ n n n [1.. 5] ] = [1,4,9,16,25]

FP 2005 2.134 162 General shape: Examples: List Comprehensions [ term generator {, generator_or_constraint [ n n n [1.. 5] ] = [1,4,9,16,25] [ n n n [1.. 10], even n ] } ]

FP 2005 2.135 163 General shape: Examples: List Comprehensions [ term generator {, generator_or_constraint [ n n n [1.. 5] ] = [1,4,9,16,25] [ n n n [1.. 10], even n ] = [4,16,36,64,100] } ]

FP 2005 2.136 164 General shape: Examples: List Comprehensions [ term generator {, generator_or_constraint [ n n n [1.. 5] ] = [1,4,9,16,25] [ n n n [1.. 10], even n ] = [4,16,36,64,100] [ m n m [1,3,5], n [2,4,6] ] } ]

FP 2005 2.137 165 General shape: Examples: List Comprehensions [ term generator {, generator_or_constraint [ n n n [1.. 5] ] = [1,4,9,16,25] [ n n n [1.. 10], even n ] = [4,16,36,64,100] } ] [ m n m [1,3,5], n [2,4,6] ] = [2,4,6,6,12,18,10,20,30]

FP 2005 2.138 166 General shape: Examples: List Comprehensions [ term generator {, generator_or_constraint [ n n n [1.. 5] ] = [1,4,9,16,25] [ n n n [1.. 10], even n ] = [4,16,36,64,100] } ] [ m n m [1,3,5], n [2,4,6] ] = [2,4,6,6,12,18,10,20,30] Note: The left generator generates slower.

FP 2005 2.139 167 General shape: Examples: List Comprehensions [ term generator {, generator_or_constraint [ n n n [1.. 5] ] = [1,4,9,16,25] [ n n n [1.. 10], even n ] = [4,16,36,64,100] } ] [ m n m [1,3,5], n [2,4,6] ] = [2,4,6,6,12,18,10,20,30] Note: The left generator generates slower. Haskell code fragments will frequently be presented like above in a form that is more readable than plain typewriter text in that case, the comes from arrow <- in generators turns into

FP 2005 3.2 170 The Type Language Haskell has a full-fledged type language, with Simple predefined datatypes: Bool, Char, Integer, Predefined type constructors: lists, tuples, functions, Type synonyms User-defined datatypes and type constructors Type variables to express parametric polymorphism

FP 2005 3.3 171 Simple Predefined Datatypes Bool truth values False, True Char Unicode characters (in GHC: ISO-10646) Integer integers arbitrary precision Int machine integers 32 bits Float real floating point single precision Double real floating point double precision Complex Float complex floating point single precision Complex Double complex floating point double precision

FP 2005 3.4 172 List Types If t is a type, then the list type [t] is the type of lists with elements of type t.

FP 2005 3.5 173 List Types If t is a type, then the list type [t] is the type of lists with elements of type t. answer :: Integer answer = 42 limit :: Int limit = 100

FP 2005 3.6 174 List Types If t is a type, then the list type [t] is the type of lists with elements of type t. answer :: Integer answer = 42 limit :: Int limit = 100 Then: [ 1, 2, 3, answer] ::???

FP 2005 3.7 175 List Types If t is a type, then the list type [t] is the type of lists with elements of type t. answer :: Integer answer = 42 limit :: Int limit = 100 Then: [ 1, 2, 3, answer] :: [Integer]

FP 2005 3.8 176 List Types If t is a type, then the list type [t] is the type of lists with elements of type t. answer :: Integer answer = 42 limit :: Int limit = 100 Then: [ 1, 2, 3, answer] :: [Integer] [ 1.. limit ] ::???

FP 2005 3.9 177 List Types If t is a type, then the list type [t] is the type of lists with elements of type t. answer :: Integer answer = 42 limit :: Int limit = 100 Then: [ 1, 2, 3, answer] :: [Integer] [ 1.. limit ] :: [Int]

FP 2005 3.10 178 List Types If t is a type, then the list type [t] is the type of lists with elements of type t. answer :: Integer answer = 42 limit :: Int limit = 100 Then: [ 1, 2, 3, answer] :: [Integer] [ 1.. limit ] :: [Int] [ [ 1.. limit ], [ 2.. limit ] ] ::???

FP 2005 3.11 179 List Types If t is a type, then the list type [t] is the type of lists with elements of type t. answer :: Integer answer = 42 limit :: Int limit = 100 Then: [ 1, 2, 3, answer] :: [Integer] [ 1.. limit ] :: [Int] [ [ 1.. limit ], [ 2.. limit ] ] :: [[Int]]

FP 2005 3.12 180 List Types If t is a type, then the list type [t] is the type of lists with elements of type t. answer :: Integer answer = 42 limit :: Int limit = 100 Then: [ 1, 2, 3, answer] :: [Integer] [ 1.. limit ] :: [Int] [ [ 1.. limit ], [ 2.. limit ] ] :: [[Int]] [ h, e, l, l, o ] ::???

FP 2005 3.13 181 List Types If t is a type, then the list type [t] is the type of lists with elements of type t. answer :: Integer answer = 42 limit :: Int limit = 100 Then: [ 1, 2, 3, answer] :: [Integer] [ 1.. limit ] :: [Int] [ [ 1.. limit ], [ 2.. limit ] ] :: [[Int]] [ h, e, l, l, o ] :: [Char]

FP 2005 3.14 182 List Types If t is a type, then the list type [t] is the type of lists with elements of type t. answer :: Integer answer = 42 limit :: Int limit = 100 Then: [ 1, 2, 3, answer] :: [Integer] [ 1.. limit ] :: [Int] [ [ 1.. limit ], [ 2.. limit ] ] :: [[Int]] [ h, e, l, l, o ] :: [Char] "hello" ::???

FP 2005 3.15 183 List Types If t is a type, then the list type [t] is the type of lists with elements of type t. answer :: Integer answer = 42 limit :: Int limit = 100 Then: [ 1, 2, 3, answer] :: [Integer] [ 1.. limit ] :: [Int] [ [ 1.. limit ], [ 2.. limit ] ] :: [[Int]] [ h, e, l, l, o ] :: [Char] "hello" :: [Char]

FP 2005 3.16 184 List Types If t is a type, then the list type [t] is the type of lists with elements of type t. answer :: Integer answer = 42 limit :: Int limit = 100 Then: [ 1, 2, 3, answer] :: [Integer] [ 1.. limit ] :: [Int] [ [ 1.. limit ], [ 2.. limit ] ] :: [[Int]] [ h, e, l, l, o ] :: [Char] "hello" :: [Char] [ "hello", "world" ] ::???

FP 2005 3.17 185 List Types If t is a type, then the list type [t] is the type of lists with elements of type t. answer :: Integer answer = 42 limit :: Int limit = 100 Then: [ 1, 2, 3, answer] :: [Integer] [ 1.. limit ] :: [Int] [ [ 1.. limit ], [ 2.. limit ] ] :: [[Int]] [ h, e, l, l, o ] :: [Char] "hello" :: [Char] [ "hello", "world" ] :: [[Char]]

FP 2005 3.18 186 List Types If t is a type, then the list type [t] is the type of lists with elements of type t. answer :: Integer answer = 42 limit :: Int limit = 100 Then: [ 1, 2, 3, answer] :: [Integer] [ 1.. limit ] :: [Int] [ [ 1.. limit ], [ 2.. limit ] ] :: [[Int]] [ h, e, l, l, o ] :: [Char] "hello" :: [Char] [ "hello", "world" ] :: [[Char]] [["first", "line"], ["second", "line"]] ::???

FP 2005 3.19 187 List Types If t is a type, then the list type [t] is the type of lists with elements of type t. answer :: Integer answer = 42 limit :: Int limit = 100 Then: [ 1, 2, 3, answer] :: [Integer] [ 1.. limit ] :: [Int] [ [ 1.. limit ], [ 2.. limit ] ] :: [[Int]] [ h, e, l, l, o ] :: [Char] "hello" :: [Char] [ "hello", "world" ] :: [[Char]] [["first", "line"], ["second", "line"]] :: [[[Char]]]

FP 2005 3.20 188 Product Types (Pairs) If t and u are types, then the product type (t,u) is the type of pairs with first component of type t and second component of type u (mathematically: t u).

FP 2005 3.21 189 Product Types (Pairs) If t and u are types, then the product type (t,u) is the type of pairs with first component of type t and second component of type u (mathematically: t u). Examples: (answer, limit) ::???

FP 2005 3.22 190 Product Types (Pairs) If t and u are types, then the product type (t,u) is the type of pairs with first component of type t and second component of type u (mathematically: t u). Examples: (answer, limit) :: (Integer, Int)

FP 2005 3.23 191 Product Types (Pairs) If t and u are types, then the product type (t,u) is the type of pairs with first component of type t and second component of type u (mathematically: t u). Examples: (answer, limit) :: (Integer, Int) (limit, answer) ::???

FP 2005 3.24 192 Product Types (Pairs) If t and u are types, then the product type (t,u) is the type of pairs with first component of type t and second component of type u (mathematically: t u). Examples: (answer, limit) :: (Integer, Int) (limit, answer) :: (Int, Integer)

FP 2005 3.25 193 Product Types (Pairs) If t and u are types, then the product type (t,u) is the type of pairs with first component of type t and second component of type u (mathematically: t u). Examples: (answer, limit) :: (Integer, Int) (limit, answer) :: (Int, Integer) ("???", answer) ::???

FP 2005 3.26 194 Product Types (Pairs) If t and u are types, then the product type (t,u) is the type of pairs with first component of type t and second component of type u (mathematically: t u). Examples: (answer, limit) :: (Integer, Int) (limit, answer) :: (Int, Integer) ("???", answer) :: ([Char], Integer)

FP 2005 3.27 195 Product Types (Pairs) If t and u are types, then the product type (t,u) is the type of pairs with first component of type t and second component of type u (mathematically: t u). Examples: (answer, limit) :: (Integer, Int) (limit, answer) :: (Int, Integer) ("???", answer) :: ([Char], Integer) ("???", (limit, answer)) ::???

FP 2005 3.28 196 Product Types (Pairs) If t and u are types, then the product type (t,u) is the type of pairs with first component of type t and second component of type u (mathematically: t u). Examples: (answer, limit) :: (Integer, Int) (limit, answer) :: (Int, Integer) ("???", answer) :: ([Char], Integer) ("???", (limit, answer)) :: ([Char], (Int, Integer))

FP 2005 3.29 197 Product Types (Pairs) If t and u are types, then the product type (t,u) is the type of pairs with first component of type t and second component of type u (mathematically: t u). Examples: (answer, limit) :: (Integer, Int) (limit, answer) :: (Int, Integer) ("???", answer) :: ([Char], Integer) ("???", (limit, answer)) :: ([Char], (Int, Integer)) ("???", X ) ::???

FP 2005 3.30 198 Product Types (Pairs) If t and u are types, then the product type (t,u) is the type of pairs with first component of type t and second component of type u (mathematically: t u). Examples: (answer, limit) :: (Integer, Int) (limit, answer) :: (Int, Integer) ("???", answer) :: ([Char], Integer) ("???", (limit, answer)) :: ([Char], (Int, Integer)) ("???", X ) :: ([Char], Char)

FP 2005 3.31 199 Product Types (Pairs) If t and u are types, then the product type (t,u) is the type of pairs with first component of type t and second component of type u (mathematically: t u). Examples: (answer, limit) :: (Integer, Int) (limit, answer) :: (Int, Integer) ("???", answer) :: ([Char], Integer) ("???", (limit, answer)) :: ([Char], (Int, Integer)) ("???", X ) :: ([Char], Char) (limit, ("???", X )) ::???

FP 2005 3.32 200 Product Types (Pairs) If t and u are types, then the product type (t,u) is the type of pairs with first component of type t and second component of type u (mathematically: t u). Examples: (answer, limit) :: (Integer, Int) (limit, answer) :: (Int, Integer) ("???", answer) :: ([Char], Integer) ("???", (limit, answer)) :: ([Char], (Int, Integer)) ("???", X ) :: ([Char], Char) (limit, ("???", X )) :: (Int, ([Char], Char))

FP 2005 3.33 201 Product Types (Pairs) If t and u are types, then the product type (t,u) is the type of pairs with first component of type t and second component of type u (mathematically: t u). Examples: (answer, limit) :: (Integer, Int) (limit, answer) :: (Int, Integer) ("???", answer) :: ([Char], Integer) ("???", (limit, answer)) :: ([Char], (Int, Integer)) ("???", X ) :: ([Char], Char) (limit, ("???", X )) :: (Int, ([Char], Char)) (True, [("X",limit),("Y",5)]) ::???

FP 2005 3.34 202 Product Types (Pairs) If t and u are types, then the product type (t,u) is the type of pairs with first component of type t and second component of type u (mathematically: t u). Examples: (answer, limit) :: (Integer, Int) (limit, answer) :: (Int, Integer) ("???", answer) :: ([Char], Integer) ("???", (limit, answer)) :: ([Char], (Int, Integer)) ("???", X ) :: ([Char], Char) (limit, ("???", X )) :: (Int, ([Char], Char)) (True, [("X",limit),("Y",5)]) :: (Bool, [([Char], Int)])

FP 2005 3.35 203 Tuple Types If n / 1 is a natural number and t 1,, t n are types, then the tuple type ( t 1,, t n ) is the type of n-tuples with the ith component of type t i. Examples: (answer, c, limit) :: (Integer, Char, Int) (answer, c, limit, "all") :: (Integer, Char, Int, [Char]) () :: () there is exactly one zero-tuple. The type () of zero-tuples is also called the unit type.

FP 2005 3.36 204 Simple Type Synonyms If t is a type not containing any type variables, and Name is an identifier with a capital first letter, then type Name = t defines Name as a type synonym for t, i.e., Name can now be used interchangeably with t. Examples: type String = [Char] predefined type Point = (Double, Double) (1.5, 2.7) type Triangle = (Point, Point, Point) type CharEntity = (Char, String) ( ü, "ü") type Dictionary = [(String,String)] [("day","jour")]

FP 2005 3.37 205 Type Variables and Polymorphic Types Identifiers with lower-case first letter can be used as type variables. Type variables can be used like other types in the construction of types, e.g.: [(a,b)] (Bool, (a, Int)) [ ( String, [(key, val)] ) ] A type containing at least one type variable is called polymorphic Polymorphic types can be instantiated by instantiating type variables with types, e.g.: [(a,b)] [(Char,b)] [(a,b)] [(Char,Int)] [(a,b)] [(a,[(string,int)])] [(a,b)] [(a,[(string,c)])]

FP 2005 3.38 206 Typing of List Construction The empty list can be used at any list type: [] :: [a] If an element x :: a and a list xs :: [a] are given, then (x : xs) :: [a] Examples: 2 :: Int [] :: [Int] [2] = 2 : [] :: [Int] [[3,4,5], [6,7]] :: [[Int]] [2] : [[3,4,5], [6,7]] :: [[Int]] 1 : ([2] : [[3,4,5], [6,7]]) cannot be typed!

FP 2005 3.39 207 Function Types and Function Application If t and u are types, then the function type t->u is the type of all functions accepting arguments of type t and producing results of type u (mathematically: t u). Then: If a function f :: a -> b and an argument x :: a are given, then we have (f x) :: b. If a function f :: a -> b is given and we know that (f x) :: b, then the argument x is used at type a. If an argument x :: a is given and we know that (f x) :: b, then the function f is used at type a -> b.

FP 2005 3.40 208 fst :: (a,b) -> a fst (x,y) = x Type Inference Examples fst ( c, False)

FP 2005 3.41 209 fst :: (a,b) -> a fst (x,y) = x Type Inference Examples fst ( c, False) :: Char

FP 2005 3.42 210 fst :: (a,b) -> a fst (x,y) = x Type Inference Examples fst ( c, False) :: Char ["hello", fst (x, 17)]

FP 2005 3.43 211 fst :: (a,b) -> a fst (x,y) = x Type Inference Examples fst ( c, False) :: Char ["hello", fst (x, 17)] x :: String

FP 2005 3.44 212 fst :: (a,b) -> a fst (x,y) = x Type Inference Examples fst ( c, False) :: Char ["hello", fst (x, 17)] x :: String f p = limit + fst p

FP 2005 3.45 213 fst :: (a,b) -> a fst (x,y) = x Type Inference Examples fst ( c, False) :: Char ["hello", fst (x, 17)] x :: String f p = limit + fst p p :: (Int,a)

FP 2005 3.46 214 fst :: (a,b) -> a fst (x,y) = x Type Inference Examples fst ( c, False) :: Char ["hello", fst (x, 17)] x :: String f p = limit + fst p p :: (Int,a) f :: (Int,a) -> Int

FP 2005 3.47 215 fst :: (a,b) -> a fst (x,y) = x Type Inference Examples fst ( c, False) :: Char ["hello", fst (x, 17)] x :: String f p = limit + fst p p :: (Int,a) f :: (Int,a) -> Int g h = fst (h "") : [limit]

FP 2005 3.48 216 fst :: (a,b) -> a fst (x,y) = x Type Inference Examples fst ( c, False) :: Char ["hello", fst (x, 17)] x :: String f p = limit + fst p p :: (Int,a) f :: (Int,a) -> Int g h = fst (h "") : [limit] h :: String -> (Int,a)

FP 2005 3.49 217 Let s Play the Evaluation Game Again 1 h1 :: String -> (Int, String) h1 str = (length str, : str) g h = fst (h "") : [limit]

FP 2005 3.50 218 Let s Play the Evaluation Game Again 1 h1 :: String -> (Int, String) h1 str = (length str, : str) g h = fst (h "") : [limit] Then: g h1

FP 2005 3.51 219 Let s Play the Evaluation Game Again 1 h1 :: String -> (Int, String) h1 str = (length str, : str) g h = fst (h "") : [limit] Then: g h1 = fst (h1 "") : [limit]

FP 2005 3.52 220 Let s Play the Evaluation Game Again 1 h1 :: String -> (Int, String) h1 str = (length str, : str) g h = fst (h "") : [limit] Then: g h1 = fst (h1 "") : [limit] = fst (length "", : "") : [limit]

FP 2005 3.53 221 Let s Play the Evaluation Game Again 1 h1 :: String -> (Int, String) h1 str = (length str, : str) g h = fst (h "") : [limit] Then: g h1 = fst (h1 "") : [limit] = fst (length "", : "") : [limit] = length "" : [limit]

FP 2005 3.54 222 Let s Play the Evaluation Game Again 1 h1 :: String -> (Int, String) h1 str = (length str, : str) g h = fst (h "") : [limit] Then: g h1 = fst (h1 "") : [limit] = fst (length "", : "") : [limit] = length "" : [limit] = 0 : [limit]

FP 2005 3.55 223 Let s Play the Evaluation Game Again 1 h1 :: String -> (Int, String) h1 str = (length str, : str) g h = fst (h "") : [limit] Then: g h1 = fst (h1 "") : [limit] = fst (length "", : "") : [limit] = length "" : [limit] = 0 : [limit] = [0, 100]

FP 2005 3.56 224 Let s Play the Evaluation Game Again 2 h2 :: String -> (Int, Char) h2 str = (sum (map ord (notocccaps str)), head str) notocccaps :: String -> String notocccaps str = filter ( notelem str) [ A.. Z ] g h = fst (h "") : [limit]

FP 2005 3.57 225 Let s Play the Evaluation Game Again 2 h2 :: String -> (Int, Char) h2 str = (sum (map ord (notocccaps str)), head str) notocccaps :: String -> String notocccaps str = filter ( notelem str) [ A.. Z ] g h = fst (h "") : [limit] Then: g h2

FP 2005 3.58 226 Let s Play the Evaluation Game Again 2 h2 :: String -> (Int, Char) h2 str = (sum (map ord (notocccaps str)), head str) notocccaps :: String -> String notocccaps str = filter ( notelem str) [ A.. Z ] g h = fst (h "") : [limit] Then: g h2 = fst (h2 "") : [limit]

FP 2005 3.59 227 Let s Play the Evaluation Game Again 2 h2 :: String -> (Int, Char) h2 str = (sum (map ord (notocccaps str)), head str) notocccaps :: String -> String notocccaps str = filter ( notelem str) [ A.. Z ] g h = fst (h "") : [limit] Then: g h2 = fst (h2 "") : [limit] = fst (sum (map ord (notocccaps "")), head "") : [limit]

FP 2005 3.60 228 Let s Play the Evaluation Game Again 2 h2 :: String -> (Int, Char) h2 str = (sum (map ord (notocccaps str)), head str) notocccaps :: String -> String notocccaps str = filter ( notelem str) [ A.. Z ] g h = fst (h "") : [limit] Then: g h2 = fst (h2 "") : [limit] = fst (sum (map ord (notocccaps "")), head "") : [limit] = sum (map ord (notocccaps "")) : [limit]

FP 2005 3.61 229 Let s Play the Evaluation Game Again 2 h2 :: String -> (Int, Char) h2 str = (sum (map ord (notocccaps str)), head str) notocccaps :: String -> String notocccaps str = filter ( notelem str) [ A.. Z ] g h = fst (h "") : [limit] Then: g h2 = fst (h2 "") : [limit] = fst (sum (map ord (notocccaps "")), head "") : [limit] = sum (map ord (notocccaps "")) : [limit] =

FP 2005 3.62 230 Let s Play the Evaluation Game Again 2 h2 :: String -> (Int, Char) h2 str = (sum (map ord (notocccaps str)), head str) notocccaps :: String -> String notocccaps str = filter ( notelem str) [ A.. Z ] g h = fst (h "") : [limit] Then: g h2 = fst (h2 "") : [limit] = fst (sum (map ord (notocccaps "")), head "") : [limit] = sum (map ord (notocccaps "")) : [limit] = = 2015 : [limit]

FP 2005 3.63 231 Let s Play the Evaluation Game Again 2 h2 :: String -> (Int, Char) h2 str = (sum (map ord (notocccaps str)), head str) notocccaps :: String -> String notocccaps str = filter ( notelem str) [ A.. Z ] g h = fst (h "") : [limit] Then: g h2 = fst (h2 "") : [limit] = fst (sum (map ord (notocccaps "")), head "") : [limit] = sum (map ord (notocccaps "")) : [limit] = = 2015 : [limit] = [2015, 100]

FP 2005 3.64 232 g h = fst (h "") : [limit] Higher-Order Functions

FP 2005 3.65 233 Higher-Order Functions g h = fst (h "") : [limit] Functional Programming: Functions are first-class citizens

FP 2005 3.66 234 Higher-Order Functions g h = fst (h "") : [limit] Functional Programming: Functions are first-class citizens Functions can be arguments of other functions: g h2

FP 2005 3.67 235 Higher-Order Functions g h = fst (h "") : [limit] Functional Programming: Functions are first-class citizens Functions can be arguments of other functions: g h2 Functions can be components of data structures: (7,h1), [h1, h2]

FP 2005 3.68 236 Higher-Order Functions g h = fst (h "") : [limit] Functional Programming: Functions are first-class citizens Functions can be arguments of other functions: g h2 Functions can be components of data structures: (7,h1), [h1, h2] Functions can be results of function application: succ. succ

FP 2005 3.69 237 Higher-Order Functions g h = fst (h "") : [limit] Functional Programming: Functions are first-class citizens Functions can be arguments of other functions: g h2 Functions can be components of data structures: (7,h1), [h1, h2] Functions can be results of function application: succ. succ A first-order function accepts only non-functional values as arguments. A higher-order function expects functions as arguments.

FP 2005 3.70 238 Higher-Order Functions g h = fst (h "") : [limit] Functional Programming: Functions are first-class citizens Functions can be arguments of other functions: g h2 Functions can be components of data structures: (7,h1), [h1, h2] Functions can be results of function application: succ. succ A first-order function accepts only non-functional values as arguments. A higher-order function expects functions as arguments. g is a second-order function: it expects first-order functions like h1, h2 as arguments.

FP 2005 3.71 239 fst :: (a,b) -> a fst (x,y) = x Type Inference Examples fst ( c, False) :: Char ["hello", fst (x, 17)] x :: String f p = limit + fst p p :: (Int,a) f :: (Int,a) -> Int g h = fst (h "") : [limit] h :: String -> (Int,a)

FP 2005 3.72 240 fst :: (a,b) -> a fst (x,y) = x Type Inference Examples fst ( c, False) :: Char ["hello", fst (x, 17)] x :: String f p = limit + fst p p :: (Int,a) f :: (Int,a) -> Int g h = fst (h "") : [limit] h :: String -> (Int,a) g :: (String -> (Int,a)) -> [Int]

FP 2005 3.73 241 Curried Functions Function application associates to the left, i.e., f x y = (f x) y

FP 2005 3.74 242 Curried Functions Function application associates to the left, i.e., f x y = (f x) y Multi-argument functions in Haskell are typically defined as curried function, i.e., they accept their arguments one at a time : cylvol r h = (pi :: Double) * r * r * h

FP 2005 3.75 243 Curried Functions Function application associates to the left, i.e., f x y = (f x) y Multi-argument functions in Haskell are typically defined as curried function, i.e., they accept their arguments one at a time : cylvol r h = (pi :: Double) * r * r * h Since the right-hand side, r, and h obviously all have type Double, we have; (cylvol r) ::???

FP 2005 3.76 244 Curried Functions Function application associates to the left, i.e., f x y = (f x) y Multi-argument functions in Haskell are typically defined as curried function, i.e., they accept their arguments one at a time : cylvol r h = (pi :: Double) * r * r * h Since the right-hand side, r, and h obviously all have type Double, we have; (cylvol r) :: Double -> Double

FP 2005 3.77 245 Curried Functions Function application associates to the left, i.e., f x y = (f x) y Multi-argument functions in Haskell are typically defined as curried function, i.e., they accept their arguments one at a time : cylvol r h = (pi :: Double) * r * r * h Since the right-hand side, r, and h obviously all have type Double, we have; (cylvol r) :: Double -> Double cylvol ::???

FP 2005 3.78 246 Curried Functions Function application associates to the left, i.e., f x y = (f x) y Multi-argument functions in Haskell are typically defined as curried function, i.e., they accept their arguments one at a time : cylvol r h = (pi :: Double) * r * r * h Since the right-hand side, r, and h obviously all have type Double, we have; (cylvol r) :: Double -> Double cylvol :: Double -> (Double -> Double)

FP 2005 3.79 247 Curried Functions Function application associates to the left, i.e., f x y = (f x) y Multi-argument functions in Haskell are typically defined as curried function, i.e., they accept their arguments one at a time : cylvol r h = (pi :: Double) * r * r * h Since the right-hand side, r, and h obviously all have type Double, we have; (cylvol r) :: Double -> Double cylvol :: Double -> (Double -> Double) Function type construction associates to the right, i.e., a -> b -> c = a -> (b -> c)

FP 2005 3.80 248 Partial Application Let values with the following types be given: f :: a b c x :: a y :: b

FP 2005 3.81 249 Partial Application Let values with the following types be given: f :: a b c x :: a y :: b The type of f is the function type a ( b c )

FP 2005 3.82 250 Partial Application Let values with the following types be given: f :: a b c x :: a y :: b The type of f is the function type a ( b c ), with argument type a, result type b c.

FP 2005 3.83 251 Partial Application Let values with the following types be given: f :: a b c x :: a y :: b The type of f is the function type a ( b c ), with argument type a, result type b c. Therefore, we can apply f to x and obtain:

FP 2005 3.84 252 Partial Application Let values with the following types be given: f :: a b c x :: a y :: b The type of f is the function type a ( b c ), with argument type a, result type b c. Therefore, we can apply f to x and obtain: ( f x ) :: b c

FP 2005 3.85 253 Partial Application Let values with the following types be given: f :: a b c x :: a y :: b The type of f is the function type a ( b c ), with argument type a, result type b c. Therefore, we can apply f to x and obtain: ( f x ) :: b c The application of a two-argument function to a single argument is a one-argument function

FP 2005 3.86 254 Partial Application Let values with the following types be given: f :: a b c x :: a y :: b The type of f is the function type a ( b c ), with argument type a, result type b c. Therefore, we can apply f to x and obtain: ( f x ) :: b c The application of a two-argument function to a single argument is a one-argument function, which can then be applied to a second argument: ( f x ) y :: c = f x y

FP 2005 3.87 255 g :: ( String ( Int, a ) ) [ Int ] g h = fst ( h "") : [ limit ] Partial Application Example

FP 2005 3.88 256 g :: ( String ( Int, a ) ) [ Int ] g h = fst ( h "") : [ limit ] Partial Application Example k n str = ( n ( length str + 1), unwords ( replicate n str ) )

FP 2005 3.89 257 g :: ( String ( Int, a ) ) [ Int ] g h = fst ( h "") : [ limit ] Partial Application Example k :: Int String ( Int, String ) k n str = ( n ( length str + 1), unwords ( replicate n str ) )

FP 2005 3.90 258 g :: ( String ( Int, a ) ) [ Int ] g h = fst ( h "") : [ limit ] Partial Application Example k :: Int String ( Int, String ) k n str = ( n ( length str + 1), unwords ( replicate n str ) ) g ( k 3)

FP 2005 3.91 259 g :: ( String ( Int, a ) ) [ Int ] g h = fst ( h "") : [ limit ] Partial Application Example k :: Int String ( Int, String ) k n str = ( n ( length str + 1), unwords ( replicate n str ) ) g ( k 3) = fst ( k 3 "") : [ limit ]

FP 2005 3.92 260 g :: ( String ( Int, a ) ) [ Int ] g h = fst ( h "") : [ limit ] Partial Application Example k :: Int String ( Int, String ) k n str = ( n ( length str + 1), unwords ( replicate n str ) ) g ( k 3) = fst ( k 3 "") : [ limit ] = fst (3 ( length "" + 1), unwords ( replicate 3 "") ) : [ limit ]

FP 2005 3.93 261 g :: ( String ( Int, a ) ) [ Int ] g h = fst ( h "") : [ limit ] Partial Application Example k :: Int String ( Int, String ) k n str = ( n ( length str + 1), unwords ( replicate n str ) ) g ( k 3) = fst ( k 3 "") : [ limit ] = fst (3 ( length "" + 1), unwords ( replicate 3 "") ) : [ limit ] = (3 ( length "" + 1) ) : [ limit ]

FP 2005 3.94 262 g :: ( String ( Int, a ) ) [ Int ] g h = fst ( h "") : [ limit ] Partial Application Example k :: Int String ( Int, String ) k n str = ( n ( length str + 1), unwords ( replicate n str ) ) g ( k 3) = fst ( k 3 "") : [ limit ] = fst (3 ( length "" + 1), unwords ( replicate 3 "") ) : [ limit ] = (3 ( length "" + 1) ) : [ limit ] = (3 (0 + 1) ) : [ limit ]

FP 2005 3.95 263 g :: ( String ( Int, a ) ) [ Int ] g h = fst ( h "") : [ limit ] Partial Application Example k :: Int String ( Int, String ) k n str = ( n ( length str + 1), unwords ( replicate 3 str ) ) g ( k 3) = fst ( k 3 "") : [ limit ] = fst (3 ( length "" + 1), unwords ( replicate n "") ) : [ limit ] = (3 ( length "" + 1) ) : [ limit ] = (3 (0 + 1) ) : [ limit ] = (3 1) : [ limit ]

FP 2005 3.96 264 g :: ( String ( Int, a ) ) [ Int ] g h = fst ( h "") : [ limit ] Partial Application Example k :: Int String ( Int, String ) k n str = ( n ( length str + 1), unwords ( replicate n str ) ) g ( k 3) = fst ( k 3 "") : [ limit ] = fst (3 ( length "" + 1), unwords ( replicate 3 "") ) : [ limit ] = (3 ( length "" + 1) ) : [ limit ] = (3 (0 + 1) ) : [ limit ] = (3 1) : [ limit ] = 3 : [ limit ]

FP 2005 3.97 265 g :: ( String ( Int, a ) ) [ Int ] g h = fst ( h "") : [ limit ] Partial Application Example k :: Int String ( Int, String ) k n str = ( n ( length str + 1), unwords ( replicate n str ) ) g ( k 3) = fst ( k 3 "") : [ limit ] = fst (3 ( length "" + 1), unwords ( replicate 3 "") ) : [ limit ] = (3 ( length "" + 1) ) : [ limit ] = (3 (0 + 1) ) : [ limit ] = (3 1) : [ limit ] = 3 : [ limit ] = [3, 100]

FP 2005 3.98 266 Operations on Functions id :: a -> a id x = x identity function (.) :: (b -> c) -> (a -> b) -> (a -> c) function composition (f. g) x = f (g x) flip :: (a -> b -> c) -> (b -> a -> c) flip f x y = f y x curry :: ((a,b) -> c) -> (a -> b -> c) curry g x y = g (x,y) argument swapping currying uncurry :: (a -> b -> c) -> ((a,b) -> c) uncurry f (x,y) = f x y Exercise (necessary!): Copy only the definitions to a sheet of paper, and then infer the types yourself!

FP 2005 3.99 267 Operator Sections Infix operators are turned into functions by surrounding them with parentheses: This is necessary in type declarations: (+) 2 3 = 2 + 3 (+) :: Int -> Int -> Int not the natural type of (+) (:) :: a -> [a] -> [a] (++) :: [a] -> [a] -> [a] It is also possible to supply only one argument (which has to be an atomic expression): (2 +) 3 = 2 + 3 = (+ 3 ) 2 (8,3 /) 2.5 = 8.3 / 2.5 = (/ 2.5) 8.3 (7 :) [] = 7 : [] = (: [] ) 7 ((2^17) :) (16:[]) = (2^17) : 16 : [] = (: (16:[])) (2^17)

FP 2005 3.100 268 Turning Functions into Infix Operators Surrounding a function name by backquotes turns it into an infix operator. Frequently used examples (not the natural types throughout): div, mod, max, min :: Int -> Int -> Int elem :: Int -> [Int] -> Bool 12 div 7 = 1 12 mod 7 = 5 12 max 7 = 12 12 min 7 = 7 12 elem [1.. 10] = False

FP 2005 3.101 269 Defining Functions Over Lists by Pattern Matching Some functions taking lists as arguments can be defined directly via pattern matching: null :: [ a ] Bool

FP 2005 3.102 270 Defining Functions Over Lists by Pattern Matching Some functions taking lists as arguments can be defined directly via pattern matching: null null [ ] = :: [ a ] Bool

FP 2005 3.103 271 Defining Functions Over Lists by Pattern Matching Some functions taking lists as arguments can be defined directly via pattern matching: null null [ ] = null ( x : xs ) = :: [ a ] Bool

FP 2005 3.104 272 Defining Functions Over Lists by Pattern Matching Some functions taking lists as arguments can be defined directly via pattern matching: null null [ ] :: [ a ] Bool = True null ( x : xs ) =

FP 2005 3.105 273 Defining Functions Over Lists by Pattern Matching Some functions taking lists as arguments can be defined directly via pattern matching: null null [ ] :: [ a ] Bool = True null ( x : xs ) = False

FP 2005 3.106 274 Defining Functions Over Lists by Pattern Matching Some functions taking lists as arguments can be defined directly via pattern matching: null null [ ] :: [ a ] Bool = True null ( x : xs ) = False head :: [ a ] a

FP 2005 3.107 275 Defining Functions Over Lists by Pattern Matching Some functions taking lists as arguments can be defined directly via pattern matching: null null [ ] :: [ a ] Bool = True null ( x : xs ) = False head :: [ a ] a head ( x : xs ) = x

FP 2005 3.108 276 Defining Functions Over Lists by Pattern Matching Some functions taking lists as arguments can be defined directly via pattern matching: null null [ ] :: [ a ] Bool = True null ( x : xs ) = False head :: [ a ] a head ( x : xs ) = x tail :: [ a ] [ a ]

FP 2005 3.109 277 Defining Functions Over Lists by Pattern Matching Some functions taking lists as arguments can be defined directly via pattern matching: null null [ ] :: [ a ] Bool = True null ( x : xs ) = False head :: [ a ] a head ( x : xs ) = x tail :: [ a ] [ a ] tail ( x : xs ) = xs

FP 2005 3.110 278 Defining Functions Over Lists by Pattern Matching Some functions taking lists as arguments can be defined directly via pattern matching: null null [ ] :: [ a ] Bool = True null ( x : xs ) = False head :: [ a ] a head ( x : xs ) = x tail :: [ a ] [ a ] tail ( x : xs ) = xs (head and tail are partial functions both are undefined on the empty list.)

FP 2005 3.111 279 Defining Functions Over Lists by Structural Induction Many functions taking lists as arguments can be defined via structural induction: length :: [ a ] Int concat :: [ [ a ] ] [ a ] ( ++ ) :: [ a ] [ a ] [ a ] product :: [ Integer ] Integer sum :: [ Integer ] Integer ( elem ) :: Int [ Int ] Bool

FP 2005 3.112 280 Defining Functions Over Lists by Structural Induction Many functions taking lists as arguments can be defined via structural induction: length :: [ a ] Int length [ ] = length ( x : xs ) = concat :: [ [ a ] ] [ a ] concat [ ] = concat ( xs : xss ) = ( ++ ) :: [ a ] [ a ] [ a ] [ ] ++ ys = ( x : xs ) ++ ys = x elem [ ] = x elem ( y : ys ) = sum [ ] = sum ( x : xs ) = product [ ] = product ( x : xs ) = (All these functions are in the standard prelude.)

FP 2005 3.113 281 Defining Functions Over Lists by Structural Induction Many functions taking lists as arguments can be defined via structural induction: length :: [ a ] Int length [ ] = 0 length ( x : xs ) = concat :: [ [ a ] ] [ a ] concat [ ] = concat ( xs : xss ) = ( ++ ) :: [ a ] [ a ] [ a ] [ ] ++ ys = ( x : xs ) ++ ys = x elem [ ] = x elem ( y : ys ) = sum [ ] = sum ( x : xs ) = product [ ] = product ( x : xs ) = (All these functions are in the standard prelude.)

FP 2005 3.114 282 Defining Functions Over Lists by Structural Induction Many functions taking lists as arguments can be defined via structural induction: length :: [ a ] Int length [ ] = 0 length ( x : xs ) = 1 + length xs concat :: [ [ a ] ] [ a ] concat [ ] = concat ( xs : xss ) = ( ++ ) :: [ a ] [ a ] [ a ] [ ] ++ ys = ( x : xs ) ++ ys = x elem [ ] = x elem ( y : ys ) = sum [ ] = sum ( x : xs ) = product [ ] = product ( x : xs ) = (All these functions are in the standard prelude.)

FP 2005 3.115 283 Defining Functions Over Lists by Structural Induction Many functions taking lists as arguments can be defined via structural induction: length :: [ a ] Int length [ ] = 0 length ( x : xs ) = 1 + length xs concat :: [ [ a ] ] [ a ] concat [ ] = concat ( xs : xss ) = ( ++ ) :: [ a ] [ a ] [ a ] [ ] ++ ys = ys ( x : xs ) ++ ys = x elem [ ] = x elem ( y : ys ) = sum [ ] = sum ( x : xs ) = product [ ] = product ( x : xs ) = (All these functions are in the standard prelude.)

FP 2005 3.116 284 Defining Functions Over Lists by Structural Induction Many functions taking lists as arguments can be defined via structural induction: length :: [ a ] Int length [ ] = 0 length ( x : xs ) = 1 + length xs concat :: [ [ a ] ] [ a ] concat [ ] = concat ( xs : xss ) = ( ++ ) :: [ a ] [ a ] [ a ] [ ] ++ ys = ys ( x : xs ) ++ ys = x : ( xs ++ ys ) x elem [ ] = x elem ( y : ys ) = sum [ ] = sum ( x : xs ) = product [ ] = product ( x : xs ) = (All these functions are in the standard prelude.)

FP 2005 3.117 285 Defining Functions Over Lists by Structural Induction Many functions taking lists as arguments can be defined via structural induction: length :: [ a ] Int length [ ] = 0 length ( x : xs ) = 1 + length xs concat :: [ [ a ] ] [ a ] concat [ ] = [ ] concat ( xs : xss ) = ( ++ ) :: [ a ] [ a ] [ a ] [ ] ++ ys = ys ( x : xs ) ++ ys = x : ( xs ++ ys ) x elem [ ] = x elem ( y : ys ) = sum [ ] = sum ( x : xs ) = product [ ] = product ( x : xs ) = (All these functions are in the standard prelude.)

FP 2005 3.118 286 Defining Functions Over Lists by Structural Induction Many functions taking lists as arguments can be defined via structural induction: length :: [ a ] Int length [ ] = 0 length ( x : xs ) = 1 + length xs concat :: [ [ a ] ] [ a ] concat [ ] = [ ] concat ( xs : xss ) = xs ++ concat xss ( ++ ) :: [ a ] [ a ] [ a ] [ ] ++ ys = ys ( x : xs ) ++ ys = x : ( xs ++ ys ) x elem [ ] = x elem ( y : ys ) = sum [ ] = sum ( x : xs ) = product [ ] = product ( x : xs ) = (All these functions are in the standard prelude.)

FP 2005 3.119 287 Defining Functions Over Lists by Structural Induction Many functions taking lists as arguments can be defined via structural induction: length :: [ a ] Int length [ ] = 0 length ( x : xs ) = 1 + length xs concat :: [ [ a ] ] [ a ] concat [ ] = [ ] concat ( xs : xss ) = xs ++ concat xss ( ++ ) :: [ a ] [ a ] [ a ] [ ] ++ ys = ys ( x : xs ) ++ ys = x : ( xs ++ ys ) x elem [ ] = x elem ( y : ys ) = sum [ ] = 0 sum ( x : xs ) = product [ ] = product ( x : xs ) = (All these functions are in the standard prelude.)

FP 2005 3.120 288 Defining Functions Over Lists by Structural Induction Many functions taking lists as arguments can be defined via structural induction: length :: [ a ] Int length [ ] = 0 length ( x : xs ) = 1 + length xs concat :: [ [ a ] ] [ a ] concat [ ] = [ ] concat ( xs : xss ) = xs ++ concat xss ( ++ ) :: [ a ] [ a ] [ a ] [ ] ++ ys = ys ( x : xs ) ++ ys = x : ( xs ++ ys ) x elem [ ] = x elem ( y : ys ) = sum [ ] = 0 sum ( x : xs ) = x + sum xs product [ ] = product ( x : xs ) = (All these functions are in the standard prelude.)

FP 2005 3.121 289 Defining Functions Over Lists by Structural Induction Many functions taking lists as arguments can be defined via structural induction: length :: [ a ] Int length [ ] = 0 length ( x : xs ) = 1 + length xs concat :: [ [ a ] ] [ a ] concat [ ] = [ ] concat ( xs : xss ) = xs ++ concat xss ( ++ ) :: [ a ] [ a ] [ a ] [ ] ++ ys = ys ( x : xs ) ++ ys = x : ( xs ++ ys ) x elem [ ] = x elem ( y : ys ) = sum [ ] = 0 sum ( x : xs ) = x + sum xs product [ ] = 0 product ( x : xs ) = (All these functions are in the standard prelude.)

FP 2005 3.122 290 Defining Functions Over Lists by Structural Induction Many functions taking lists as arguments can be defined via structural induction: length :: [ a ] Int length [ ] = 0 length ( x : xs ) = 1 + length xs concat :: [ [ a ] ] [ a ] concat [ ] = [ ] concat ( xs : xss ) = xs ++ concat xss ( ++ ) :: [ a ] [ a ] [ a ] [ ] ++ ys = ys ( x : xs ) ++ ys = x : ( xs ++ ys ) x elem [ ] = x elem ( y : ys ) = sum [ ] = 0 sum ( x : xs ) = x + sum xs product [ ] = 0 product ( x : xs ) = x product xs (All these functions are in the standard prelude.)

FP 2005 3.123 291 Defining Functions Over Lists by Structural Induction Many functions taking lists as arguments can be defined via structural induction: length :: [ a ] Int length [ ] = 0 length ( x : xs ) = 1 + length xs concat :: [ [ a ] ] [ a ] concat [ ] = [ ] concat ( xs : xss ) = xs ++ concat xss ( ++ ) :: [ a ] [ a ] [ a ] [ ] ++ ys = ys ( x : xs ) ++ ys = x : ( xs ++ ys ) x elem [ ] = False x elem ( y : ys ) = sum [ ] = 0 sum ( x : xs ) = x + sum xs product [ ] = 0 product ( x : xs ) = x product xs (All these functions are in the standard prelude.)

FP 2005 3.124 292 Defining Functions Over Lists by Structural Induction Many functions taking lists as arguments can be defined via structural induction: length :: [ a ] Int length [ ] = 0 length ( x : xs ) = 1 + length xs concat :: [ [ a ] ] [ a ] concat [ ] = [ ] concat ( xs : xss ) = xs ++ concat xss ( ++ ) :: [ a ] [ a ] [ a ] sum [ ] = 0 [ ] ++ ys = ys sum ( x : xs ) = x + sum xs ( x : xs ) ++ ys = x : ( xs ++ ys ) product [ ] = 0 product ( x : xs ) = x product xs x elem [ ] = False x elem ( y : ys ) = x y x elem ys (All these functions are in the standard prelude.)

FP 2005 3.125 293 sign x x > 0 = 1 x == 0 = 0 x < 0 = -1 Guarded Definitions

FP 2005 3.126 294 sign x x > 0 = 1 x == 0 = 0 x < 0 = -1 Guarded Definitions choose :: Ord a ( a, b ) ( a, b ) b choose ( x, v ) ( y, w ) x > y = v x < y = w otherwise = error "I cannot decide!"

FP 2005 3.127 295 sign x x > 0 = 1 x == 0 = 0 x < 0 = -1 Guarded Definitions choose :: Ord a ( a, b ) ( a, b ) b choose ( x, v ) ( y, w ) x > y = v x < y = w otherwise = error "I cannot decide!" If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ]

FP 2005 3.128 296 sign x x > 0 = 1 x == 0 = 0 x < 0 = -1 Guarded Definitions choose :: Ord a ( a, b ) ( a, b ) b choose ( x, v ) ( y, w ) x > y = v x < y = w otherwise = error "I cannot decide!" If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3]

FP 2005 3.129 297 sign x x > 0 = 1 x == 0 = 0 x < 0 = -1 Guarded Definitions choose :: Ord a ( a, b ) ( a, b ) b choose ( x, v ) ( y, w ) x > y = v x < y = w otherwise = error "I cannot decide!" If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3] = take_while ( < 5) (1 : 2 : 3 : [ ] )

FP 2005 3.130 298 sign x x > 0 = 1 x == 0 = 0 x < 0 = -1 Guarded Definitions choose :: Ord a ( a, b ) ( a, b ) b choose ( x, v ) ( y, w ) x > y = v x < y = w otherwise = error "I cannot decide!" If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3] = take_while ( < 5) (1 : 2 : 3 : [ ] ) = 1 : take_while ( < 5) (2 : 3 : [ ] )

FP 2005 3.131 299 sign x x > 0 = 1 x == 0 = 0 x < 0 = -1 Guarded Definitions choose :: Ord a ( a, b ) ( a, b ) b choose ( x, v ) ( y, w ) x > y = v x < y = w otherwise = error "I cannot decide!" If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3] = take_while ( < 5) (1 : 2 : 3 : [ ] ) = 1 : take_while ( < 5) (2 : 3 : [ ] ) = 1 : 2 : take_while ( < 5) (3 : [ ] )

FP 2005 3.132 300 sign x x > 0 = 1 x == 0 = 0 x < 0 = -1 Guarded Definitions choose :: Ord a ( a, b ) ( a, b ) b choose ( x, v ) ( y, w ) x > y = v x < y = w otherwise = error "I cannot decide!" If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3] = take_while ( < 5) (1 : 2 : 3 : [ ] ) = 1 : take_while ( < 5) (2 : 3 : [ ] ) = 1 : 2 : take_while ( < 5) (3 : [ ] ) = 1 : 2 : 3 : take_while ( < 5) [ ]

FP 2005 3.133 301 sign x x > 0 = 1 x == 0 = 0 x < 0 = -1 Guarded Definitions choose :: Ord a ( a, b ) ( a, b ) b choose ( x, v ) ( y, w ) x > y = v x < y = w otherwise = error "I cannot decide!" If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3] = take_while ( < 5) (1 : 2 : 3 : [ ] ) = 1 : take_while ( < 5) (2 : 3 : [ ] ) = 1 : 2 : take_while ( < 5) (3 : [ ] ) = 1 : 2 : 3 : take_while ( < 5) [ ] = 1 : 2 : 3 : [ ]

FP 2005 3.134 302 sign x x > 0 = 1 x == 0 = 0 x < 0 = -1 Guarded Definitions choose :: Ord a ( a, b ) ( a, b ) b choose ( x, v ) ( y, w ) x > y = v x < y = w otherwise = error "I cannot decide!" If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3] = take_while ( < 5) (1 : 2 : 3 : [ ] ) = 1 : take_while ( < 5) (2 : 3 : [ ] ) = 1 : 2 : take_while ( < 5) (3 : [ ] ) = 1 : 2 : 3 : take_while ( < 5) [ ] = 1 : 2 : 3 : [ ] = [1, 2, 3]

FP 2005 3.135 303 Guarded Definitions Fall-Through If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ]

FP 2005 3.136 304 Guarded Definitions Fall-Through If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 3, 4, 5, 6]

FP 2005 3.137 305 Guarded Definitions Fall-Through If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 3, 4, 5, 6] = take_while ( < 5) (1 : 2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] )

FP 2005 3.138 306 Guarded Definitions Fall-Through If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 3, 4, 5, 6] = take_while ( < 5) (1 : 2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : take_while ( < 5) (2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] )

FP 2005 3.139 307 Guarded Definitions Fall-Through If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 3, 4, 5, 6] = take_while ( < 5) (1 : 2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : take_while ( < 5) (2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : take_while ( < 5) (3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] )

FP 2005 3.140 308 Guarded Definitions Fall-Through If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 3, 4, 5, 6] = take_while ( < 5) (1 : 2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : take_while ( < 5) (2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : take_while ( < 5) (3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : take_while ( < 5) (2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] )

FP 2005 3.141 309 Guarded Definitions Fall-Through If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 3, 4, 5, 6] = take_while ( < 5) (1 : 2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : take_while ( < 5) (2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : take_while ( < 5) (3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : take_while ( < 5) (2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : take_while ( < 5) (3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] )

FP 2005 3.142 310 Guarded Definitions Fall-Through If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 3, 4, 5, 6] = take_while ( < 5) (1 : 2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : take_while ( < 5) (2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : take_while ( < 5) (3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : take_while ( < 5) (2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : take_while ( < 5) (3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : take_while ( < 5) (4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] )

FP 2005 3.143 311 Guarded Definitions Fall-Through If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 3, 4, 5, 6] = take_while ( < 5) (1 : 2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : take_while ( < 5) (2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : take_while ( < 5) (3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : take_while ( < 5) (2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : take_while ( < 5) (3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : take_while ( < 5) (4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : 4 : take_while ( < 5) (3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] )

FP 2005 3.144 312 Guarded Definitions Fall-Through If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 3, 4, 5, 6] = take_while ( < 5) (1 : 2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : take_while ( < 5) (2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : take_while ( < 5) (3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : take_while ( < 5) (2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : take_while ( < 5) (3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : take_while ( < 5) (4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : 4 : take_while ( < 5) (3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : 4 : 3 : take_while ( < 5) (4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] )

FP 2005 3.145 313 Guarded Definitions Fall-Through If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 3, 4, 5, 6] = take_while ( < 5) (1 : 2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : take_while ( < 5) (2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : take_while ( < 5) (3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : take_while ( < 5) (2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : take_while ( < 5) (3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : take_while ( < 5) (4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : 4 : take_while ( < 5) (3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : 4 : 3 : take_while ( < 5) (4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : 4 : 3 : 4 : take_while ( < 5) (5 : 4 : 3 : 4 : 5 : 6 : [ ] )

FP 2005 3.146 314 Guarded Definitions Fall-Through If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 3, 4, 5, 6] = take_while ( < 5) (1 : 2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : take_while ( < 5) (2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : take_while ( < 5) (3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : take_while ( < 5) (2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : take_while ( < 5) (3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : take_while ( < 5) (4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : 4 : take_while ( < 5) (3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : 4 : 3 : take_while ( < 5) (4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : 4 : 3 : 4 : take_while ( < 5) (5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : 4 : 3 : 4 : [ ]

FP 2005 3.147 315 Guarded Definitions Fall-Through If no guard succeeds, the next pattern is tried: take_while p ( x : xs ) p x = x : take_while p xs take_while p xs = [ ] take_while ( < 5) [1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 3, 4, 5, 6] = take_while ( < 5) (1 : 2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : take_while ( < 5) (2 : 3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : take_while ( < 5) (3 : 2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : take_while ( < 5) (2 : 3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : take_while ( < 5) (3 : 4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : take_while ( < 5) (4 : 3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : 4 : take_while ( < 5) (3 : 4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : 4 : 3 : take_while ( < 5) (4 : 5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : 4 : 3 : 4 : take_while ( < 5) (5 : 4 : 3 : 4 : 5 : 6 : [ ] ) = 1 : 2 : 3 : 2 : 3 : 4 : 3 : 4 : [ ] = [1, 2, 3, 2, 3, 4, 3, 4]

FP 2005 3.148 316 case Expressions sign x = case compare x 0 of GT -> 1 EQ -> 0 LT -> -1

FP 2005 3.149 317 case Expressions sign x = case compare x 0 of GT -> 1 EQ -> 0 LT -> -1 The prelude datatype Ordering has three elements and is used mostly as result type of the prelude function compare: data Ordering = LT EQ GT

FP 2005 3.150 318 case Expressions sign x = case compare x 0 of GT -> 1 EQ -> 0 LT -> -1 The prelude datatype Ordering has three elements and is used mostly as result type of the prelude function compare: data Ordering = LT EQ GT compare :: Ord a a a Ordering

FP 2005 3.151 319 case Expressions sign x = case compare x 0 of GT -> 1 EQ -> 0 LT -> -1 The prelude datatype Ordering has three elements and is used mostly as result type of the prelude function compare: data Ordering = LT EQ GT compare :: Ord a a a Ordering Another example: choose ( x, v ) ( y, w ) = case compare x y of GT v LT w EQ error "I cannot decide!"

FP 2005 3.152 320 if then else and case Expressions The type Bool can be considered as a two-element enumeration type: data Bool = False True

FP 2005 3.153 321 if then else and case Expressions The type Bool can be considered as a two-element enumeration type: data Bool = False True Conditional expressions are syntactic sugar for case expressions over Bool: if condition then expr1 else expr2 case condition of True expr1 False expr2

FP 2005 3.154 322 if then else and case Expressions The type Bool can be considered as a two-element enumeration type: data Bool = False True Conditional expressions are syntactic sugar for case expressions over Bool: if condition then expr1 else expr2 case condition of True expr1 False expr2 Two ways of defining functions: Pattern Matching not True = False not False = True case not b = case b of True False False True

FP 2005 3.155 323 case Expressions are Anonymous Pattern Matching commawords :: [ String ] String commawords [ ] = [ ] commawords ( x : xs ) = x ++ case xs of [ ] [ ] _ ", " : commawords xs

FP 2005 3.156 324 case Expressions are Anonymous Pattern Matching commawords :: [ String ] String commawords [ ] = [ ] commawords ( x : xs ) = x ++ case xs of [ ] [ ] _ ", " : commawords xs Every use of a case expression can be transformed into the use of an auxiliary function defined by pattern matching

FP 2005 3.157 325 case Expressions are Anonymous Pattern Matching commawords :: [ String ] String commawords [ ] = [ ] commawords ( x : xs ) = x ++ case xs of [ ] [ ] _ ", " : commawords xs Every use of a case expression can be transformed into the use of an auxiliary function defined by pattern matching: commawords :: [ String ] String commawords [ ] = [ ] commawords ( x : xs ) = x ++ commawordsaux xs

FP 2005 3.158 326 case Expressions are Anonymous Pattern Matching commawords :: [ String ] String commawords [ ] = [ ] commawords ( x : xs ) = x ++ case xs of [ ] [ ] _ ", " : commawords xs Every use of a case expression can be transformed into the use of an auxiliary function defined by pattern matching: commawords :: [ String ] String commawords [ ] = [ ] commawords ( x : xs ) = x ++ commawordsaux xs commawordsaux [ ] = [ ] commawordsaux xs = ", " : commawords xs

FP 2005 3.159 327 where Clauses

FP 2005 3.160 328 where Clauses If an auxiliary definition is used only locally, it should be inside a local definition

FP 2005 3.161 329 where Clauses If an auxiliary definition is used only locally, it should be inside a local definition, e.g.: commawords :: [ String ] String commawords [ ] = [ ] commawords ( x : xs ) = x ++ commawordsaux xs where commawordsaux [ ] = [ ] commawordsaux xs = ", " : commawords xs

FP 2005 3.162 330 where Clauses If an auxiliary definition is used only locally, it should be inside a local definition, e.g.: commawords :: [ String ] String commawords [ ] = [ ] commawords ( x : xs ) = x ++ commawordsaux xs where commawordsaux [ ] = [ ] commawordsaux xs = ", " : commawords xs where clauses are visible only within their enclosing clause, here commawords ( x : xs ) =

FP 2005 3.163 331 where Clauses If an auxiliary definition is used only locally, it should be inside a local definition, e.g.: commawords :: [ String ] String commawords [ ] = [ ] commawords ( x : xs ) = x ++ commawordsaux xs where commawordsaux [ ] = [ ] commawordsaux xs = ", " : commawords xs where clauses are visible only within their enclosing clause, here commawords ( x : xs ) = where clauses are visible within all guards: f x y y > z = y == z = y < z = where z = x * x

FP 2005 3.164 332 let Expressions Local definitions can also be part of expressions: f k n = let m = k mod n in if m == 0 then n else f n m

FP 2005 3.165 333 let Expressions Local definitions can also be part of expressions: f k n = let m = k mod n in if m == 0 then n else f n m h x y = let x2 = x * x y2 = y * y in sqrt (x2 + y2)

FP 2005 3.166 334 let Expressions Local definitions can also be part of expressions: f k n = let m = k mod n in if m == 0 then n else f n m h x y = let x2 = x * x y2 = y * y in sqrt (x2 + y2) Definitions can use pattern bindings: g k n = let (d,m) = divmod k n in if d == 0 then [m] else g d n ++ [m]

FP 2005 3.167 335 let Expressions Local definitions can also be part of expressions: f k n = let m = k mod n in if m == 0 then n else f n m h x y = let x2 = x * x y2 = y * y in sqrt (x2 + y2) Definitions can use pattern bindings: g k n = let (d,m) = divmod k n in if d == 0 then [m] else g d n ++ [m] Guards, let and where bindings, and case cases all are layout sensitive!

FP 2005 3.168 336 let or where?

FP 2005 3.169 337 let or where? let bindings in expression is an expression

FP 2005 3.170 338 let or where? let bindings in expression is an expression fname patterns guardedrhss where bindings is a clause that is part of a definition

FP 2005 3.171 339 let or where? let bindings in expression is an expression fname patterns guardedrhss where bindings is a clause that is part of a definition (where clauses can also modify case cases)

FP 2005 3.172 340 let or where? let bindings in expression is an expression fname patterns guardedrhss where bindings is a clause that is part of a definition (where clauses can also modify case cases) Frequently, the choice between let and where is a matter of style: where clauses result in a top-down presentation let expressions lend themselves also to bottom-up presentations

FP 2005 3.173 341 Some Prelude Functions Elementary List Access head head (x:_) last last [x] last (_:xs) tail tail (_:xs) :: [a] -> a = x :: [a] -> a = x = last xs :: [a] -> [a] = xs init :: [a] -> [a] init [x] = [] init (x:xs) = x : init xs null null [] null (_:_) :: [a] -> Bool = True = False

FP 2005 3.174 342 Some Prelude Functions List Indexing length :: [a] -> Int length = foldl (\n _ -> n + 1) 0 (!!) :: [b] -> Int -> b (x:_)!! 0 = x (_:xs)!! n n>0 = xs!! (n-1) (_:_)!! _ = error "PreludeList.!!: negative index" []!! _ = error "PreludeList.!!: index too large"

FP 2005 3.175 343 Some Prelude Functions Positional List Splitting take :: Int -> [a] -> [a] take 0 _ = [] take _ [] = [] take n (x:xs) n>0 = x : take (n-1) xs take = error "take: negative argument" drop :: Int -> [a] -> [a] drop 0 xs = xs drop _ [] = [] drop n (_:xs) n>0 = drop (n-1) xs drop = error "drop: negative argument" splitat :: Int -> [a] -> ([a], [a]) splitat 0 xs = ([],xs) splitat _ [] = ([],[]) splitat n (x:xs) n>0 = (x:xs,xs ) where (xs,xs ) = splitat (n-1) xs splitat = error "splitat: negative argument"

FP 2005 3.176 344 Some Prelude Functions Concatenation, Iteration (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) concat :: [[a]] -> [a] concat = foldr (++) [] iterate :: (a -> a) -> a -> [a] iterate f x = x : iterate f (f x) repeat :: a -> [a] repeat x = xs where xs = x:xs { repeat x = x : repeat x } for understanding replicate :: Int -> a -> [a] replicate n x = take n (repeat x) cycle :: [a] -> [a] cycle xs = xs where xs = xs ++ xs

FP 2005 3.177 345 Separation of Concerns: Generation and Consumption

FP 2005 3.178 346 Separation of Concerns: Generation and Consumption replicate 3!

FP 2005 3.179 347 Separation of Concerns: Generation and Consumption replicate 3! = take 3 (repeat! ) replicate

FP 2005 3.180 348 Separation of Concerns: Generation and Consumption replicate 3! = take 3 (repeat! ) replicate = take 3 (! : repeat! ) repeat

FP 2005 3.181 349 Separation of Concerns: Generation and Consumption replicate 3! = take 3 (repeat! ) replicate = take 3 (! : repeat! ) repeat =! : take (3-1) (repeat! ) take (iii)

FP 2005 3.182 350 Separation of Concerns: Generation and Consumption replicate 3! = take 3 (repeat! ) replicate = take 3 (! : repeat! ) repeat =! : take (3-1) (repeat! ) take (iii) =! : take 2 (repeat! ) subtraction

FP 2005 3.183 351 Separation of Concerns: Generation and Consumption replicate 3! = take 3 (repeat! ) replicate = take 3 (! : repeat! ) repeat =! : take (3-1) (repeat! ) take (iii) =! : take 2 (repeat! ) subtraction =! : take 2 (! : repeat! ) repeat

FP 2005 3.184 352 Separation of Concerns: Generation and Consumption replicate 3! = take 3 (repeat! ) replicate = take 3 (! : repeat! ) repeat =! : take (3-1) (repeat! ) take (iii) =! : take 2 (repeat! ) subtraction =! : take 2 (! : repeat! ) repeat =! :! : take (2-1) (repeat! ) take (iii)

FP 2005 3.185 353 Separation of Concerns: Generation and Consumption replicate 3! = take 3 (repeat! ) replicate = take 3 (! : repeat! ) repeat =! : take (3-1) (repeat! ) take (iii) =! : take 2 (repeat! ) subtraction =! : take 2 (! : repeat! ) repeat =! :! : take (2-1) (repeat! ) take (iii) =! :! : take 1 (repeat! ) subtraction

FP 2005 3.186 354 Separation of Concerns: Generation and Consumption replicate 3! = take 3 (repeat! ) replicate = take 3 (! : repeat! ) repeat =! : take (3-1) (repeat! ) take (iii) =! : take 2 (repeat! ) subtraction =! : take 2 (! : repeat! ) repeat =! :! : take (2-1) (repeat! ) take (iii) =! :! : take 1 (repeat! ) subtraction =! :! : take 1 (! : repeat! ) repeat

FP 2005 3.187 355 Separation of Concerns: Generation and Consumption replicate 3! = take 3 (repeat! ) replicate = take 3 (! : repeat! ) repeat =! : take (3-1) (repeat! ) take (iii) =! : take 2 (repeat! ) subtraction =! : take 2 (! : repeat! ) repeat =! :! : take (2-1) (repeat! ) take (iii) =! :! : take 1 (repeat! ) subtraction =! :! : take 1 (! : repeat! ) repeat =! :! :! : take (1-1) (repeat! ) take (iii)

FP 2005 3.188 356 Separation of Concerns: Generation and Consumption replicate 3! = take 3 (repeat! ) replicate = take 3 (! : repeat! ) repeat =! : take (3-1) (repeat! ) take (iii) =! : take 2 (repeat! ) subtraction =! : take 2 (! : repeat! ) repeat =! :! : take (2-1) (repeat! ) take (iii) =! :! : take 1 (repeat! ) subtraction =! :! : take 1 (! : repeat! ) repeat =! :! :! : take (1-1) (repeat! ) take (iii) =! :! :! : take 0 (repeat! ) subtraction

FP 2005 3.189 357 Separation of Concerns: Generation and Consumption replicate 3! = take 3 (repeat! ) replicate = take 3 (! : repeat! ) repeat =! : take (3-1) (repeat! ) take (iii) =! : take 2 (repeat! ) subtraction =! : take 2 (! : repeat! ) repeat =! :! : take (2-1) (repeat! ) take (iii) =! :! : take 1 (repeat! ) subtraction =! :! : take 1 (! : repeat! ) repeat =! :! :! : take (1-1) (repeat! ) take (iii) =! :! :! : take 0 (repeat! ) subtraction =! :! :! : [] take (i)

FP 2005 3.190 358 Separation of Concerns: Generation and Consumption replicate 3! = take 3 (repeat! ) replicate = take 3 (! : repeat! ) repeat =! : take (3-1) (repeat! ) take (iii) =! : take 2 (repeat! ) subtraction =! : take 2 (! : repeat! ) repeat =! :! : take (2-1) (repeat! ) take (iii) =! :! : take 1 (repeat! ) subtraction =! :! : take 1 (! : repeat! ) repeat =! :! :! : take (1-1) (repeat! ) take (iii) =! :! :! : take 0 (repeat! ) subtraction =! :! :! : [] take (i) = "!!!"

FP 2005 3.191 359 What We Have Seen So Far

FP 2005 3.192 360 Functional programming: What We Have Seen So Far

FP 2005 3.193 361 What We Have Seen So Far Functional programming: Higher-order functions

FP 2005 3.194 362 What We Have Seen So Far Functional programming: Higher-order functions, functions as arguments and results

FP 2005 3.195 363 What We Have Seen So Far Functional programming: Higher-order functions, functions as arguments and results Type systems:

FP 2005 3.196 364 What We Have Seen So Far Functional programming: Higher-order functions, functions as arguments and results Type systems: type constants and type constructors

FP 2005 3.197 365 What We Have Seen So Far Functional programming: Higher-order functions, functions as arguments and results Type systems: type constants and type constructors, parametric polymorphism

FP 2005 3.198 366 What We Have Seen So Far Functional programming: Higher-order functions, functions as arguments and results Type systems: type constants and type constructors, parametric polymorphism (type variables)

FP 2005 3.199 367 What We Have Seen So Far Functional programming: Higher-order functions, functions as arguments and results Type systems: type constants and type constructors, parametric polymorphism (type variables), type inference

FP 2005 3.200 368 What We Have Seen So Far Functional programming: Higher-order functions, functions as arguments and results Type systems: type constants and type constructors, parametric polymorphism (type variables), type inference Operator precedence rules:

FP 2005 3.201 369 What We Have Seen So Far Functional programming: Higher-order functions, functions as arguments and results Type systems: type constants and type constructors, parametric polymorphism (type variables), type inference Operator precedence rules: juxtaposition as operator

FP 2005 3.202 370 What We Have Seen So Far Functional programming: Higher-order functions, functions as arguments and results Type systems: type constants and type constructors, parametric polymorphism (type variables), type inference Operator precedence rules: juxtaposition as operator, associate to the left/right

FP 2005 3.203 371 What We Have Seen So Far Functional programming: Higher-order functions, functions as arguments and results Type systems: type constants and type constructors, parametric polymorphism (type variables), type inference Operator precedence rules: juxtaposition as operator, associate to the left/right Argument passing:

FP 2005 3.204 372 What We Have Seen So Far Functional programming: Higher-order functions, functions as arguments and results Type systems: type constants and type constructors, parametric polymorphism (type variables), type inference Operator precedence rules: juxtaposition as operator, associate to the left/right Argument passing: not by value or reference

FP 2005 3.205 373 What We Have Seen So Far Functional programming: Higher-order functions, functions as arguments and results Type systems: type constants and type constructors, parametric polymorphism (type variables), type inference Operator precedence rules: juxtaposition as operator, associate to the left/right Argument passing: not by value or reference, but by name

FP 2005 3.206 374 What We Have Seen So Far Functional programming: Higher-order functions, functions as arguments and results Type systems: type constants and type constructors, parametric polymorphism (type variables), type inference Operator precedence rules: juxtaposition as operator, associate to the left/right Argument passing: not by value or reference, but by name Powerful datatypes with simple interface:

FP 2005 3.207 375 What We Have Seen So Far Functional programming: Higher-order functions, functions as arguments and results Type systems: type constants and type constructors, parametric polymorphism (type variables), type inference Operator precedence rules: juxtaposition as operator, associate to the left/right Argument passing: not by value or reference, but by name Powerful datatypes with simple interface: Integer, lists, lists of lists of

FP 2005 3.208 376 What We Have Seen So Far Functional programming: Higher-order functions, functions as arguments and results Type systems: type constants and type constructors, parametric polymorphism (type variables), type inference Operator precedence rules: juxtaposition as operator, associate to the left/right Argument passing: not by value or reference, but by name Powerful datatypes with simple interface: Integer, lists, lists of lists of Non-local control (evaluation on demand): modularity (e.g., generate / prune)

FP 2005 3.209 377 Some Prelude Functions List Splitting with Predicates takewhile :: (a -> Bool) -> [a] -> [a] takewhile p [] = [] takewhile p (x:xs) p x = x : takewhile p xs otherwise = [] dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs span, break :: (a -> Bool) -> [a] -> ([a],[a]) span p [] = ([],[]) span p xs@(x:xs ) p x = let (ys,zs) = span p xs in (x:ys,zs) otherwise = ([],xs) break p = span (not. p)

FP 2005 3.210 378 as-patterns dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs

FP 2005 3.211 379 as-patterns dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 1,2,3]:

FP 2005 3.212 380 as-patterns dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 1,2,3]: p = xs = x = xs =

FP 2005 3.213 381 as-patterns dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 1,2,3]: p = ( < 5) xs = x = xs =

FP 2005 3.214 382 as-patterns dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 1,2,3]: p = ( < 5) xs = [1,2,3] x = xs =

FP 2005 3.215 383 as-patterns dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 1,2,3]: p = ( < 5) xs = [1,2,3] x = 1 xs =

FP 2005 3.216 384 as-patterns dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 1,2,3]: p = ( < 5) xs = [1,2,3] x = 1 xs = [2,3]

FP 2005 3.217 385 as-patterns dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 1,2,3]: p = ( < 5) xs = [1,2,3] x = 1 xs = [2,3] p x = ( < 5) 1 = 1 < 5 = True

FP 2005 3.218 386 as-patterns dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 1,2,3]: p = ( < 5) xs = [1,2,3] x = 1 xs = [2,3] p x = ( < 5) 1 = 1 < 5 = True Therefore: dropwhile ( < 5) [1,2,3] =

FP 2005 3.219 387 as-patterns dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 1,2,3]: p = ( < 5) xs = [1,2,3] x = 1 xs = [2,3] p x = ( < 5) 1 = 1 < 5 = True Therefore: dropwhile ( < 5) [1,2,3] = dropwhile ( < 5) [2,3]

FP 2005 3.220 388 as-patterns 2 dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 5,4,3]:

FP 2005 3.221 389 as-patterns 2 dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 5,4,3]: p = xs = x = xs =

FP 2005 3.222 390 as-patterns 2 dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 5,4,3]: p = ( < 5) xs = x = xs =

FP 2005 3.223 391 as-patterns 2 dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 5,4,3]: p = ( < 5) xs = [5,4,3] x = xs =

FP 2005 3.224 392 as-patterns 2 dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 5,4,3]: p = ( < 5) xs = [5,4,3] x = 5 xs =

FP 2005 3.225 393 as-patterns 2 dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 5,4,3]: p = ( < 5) xs = [5,4,3] x = 5 xs = [4,3]

FP 2005 3.226 394 as-patterns 2 dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 5,4,3]: p = ( < 5) xs = [5,4,3] x = 5 xs = [4,3] p x = ( < 5) 5 = 5 < 5 = False

FP 2005 3.227 395 as-patterns 2 dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 5,4,3]: p = ( < 5) xs = [5,4,3] x = 5 xs = [4,3] p x = ( < 5) 5 = 5 < 5 = False Therefore: dropwhile ( < 5) [5,4,3] =

FP 2005 3.228 396 as-patterns 2 dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs Consider matching of the third clause against dropwhile ( < 5) [ 5,4,3]: p = ( < 5) xs = [5,4,3] x = 5 xs = [4,3] p x = ( < 5) 5 = 5 < 5 = False Therefore: dropwhile ( < 5) [5,4,3] = [5,4,3]

FP 2005 3.229 397 Some Prelude Functions List Splitting with Predicates takewhile :: (a -> Bool) -> [a] -> [a] takewhile p [] = [] takewhile p (x:xs) p x = x : takewhile p xs otherwise = [] dropwhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p xs@(x:xs ) p x = dropwhile p xs otherwise = xs span, break :: (a -> Bool) -> [a] -> ([a],[a]) span p [] = ([],[]) span p xs@(x:xs ) p x = let (ys,zs) = span p xs in (x:ys,zs) otherwise = ([],xs) break p = span (not. p)

FP 2005 3.230 398 Some Prelude Functions Text Processing lines :: String -> [String] lines "" = [] lines s = let (l,s ) = break ( \n ==) s in l : case s of [] -> [] (_:s ) -> lines s words words s :: String -> [String] = case dropwhile isspace s of "" -> [] s -> w : words s where (w,s ) = break isspace s unlines :: [String] -> String unlines [] = [] unlines (l:ls) = l ++ \n : unlines ls unwords :: [String] -> String unwords [] = "" unwords [w] = w unwords (w:ws) = w ++ : unwords ws

FP 2005 3.231 399 map and filter map :: (a -> b) -> ([a] -> [b]) map f [] = [] map f (x:xs) = f x : map f xs

FP 2005 3.232 400 map and filter map :: (a -> b) -> ([a] -> [b]) map f [] = [] map f (x:xs) = f x : map f xs filter :: (a -> Bool) -> ([a] -> [a]) filter p [] = [] filter p (x : xs) = if p x then x : rest else rest where rest = filter p xs

FP 2005 3.233 401 map and filter map :: (a -> b) -> ([a] -> [b]) map f [] = [] map f (x:xs) = f x : map f xs filter :: (a -> Bool) -> ([a] -> [a]) filter p [] = [] filter p (x : xs) = if p x then x : rest else rest where rest = filter p xs These functions could also be defined via list comprehension: map f xs = [ f x x <- xs ]

FP 2005 3.234 402 map and filter map :: (a -> b) -> ([a] -> [b]) map f [] = [] map f (x:xs) = f x : map f xs filter :: (a -> Bool) -> ([a] -> [a]) filter p [] = [] filter p (x : xs) = if p x then x : rest else rest where rest = filter p xs These functions could also be defined via list comprehension: map f xs = [ f x x <- xs ] filter p xs = [ x x <- xs, p x ]

FP 2005 3.235 403 map and filter map :: (a -> b) -> ([a] -> [b]) map f [] = [] map f (x:xs) = f x : map f xs filter :: (a -> Bool) -> ([a] -> [a]) filter p [] = [] filter p (x : xs) = if p x then x : rest else rest where rest = filter p xs These functions could also be defined via list comprehension: map f xs = [ f x x <- xs ] filter p xs = [ x x <- xs, p x ] Examples: map (7 *) [1.. 6] = [7, 14, 21, 28, 35, 42]

FP 2005 3.236 404 map and filter map :: (a -> b) -> ([a] -> [b]) map f [] = [] map f (x:xs) = f x : map f xs filter :: (a -> Bool) -> ([a] -> [a]) filter p [] = [] filter p (x : xs) = if p x then x : rest else rest where rest = filter p xs These functions could also be defined via list comprehension: map f xs = [ f x x <- xs ] filter p xs = [ x x <- xs, p x ] Examples: map (7 *) [1.. 6] = [7, 14, 21, 28, 35, 42] filter even [1.. 6] = [2, 4, 6]

FP 2005 3.237 405 foldr1 foldr1 foldr1 ( ) [x] :: (a -> a -> a) -> [a] -> a = x foldr1 ( ) (x:xs) = x (foldr1 ( ) xs)

FP 2005 3.238 406 foldr1 foldr1 foldr1 ( ) [x] :: (a -> a -> a) -> [a] -> a = x foldr1 ( ) (x:xs) = x (foldr1 ( ) xs) foldr1 ( ) [x 1, x 2, x 3, x 4, x 5 ]

FP 2005 3.239 407 foldr1 foldr1 foldr1 ( ) [x] :: (a -> a -> a) -> [a] -> a = x foldr1 ( ) (x:xs) = x (foldr1 ( ) xs) foldr1 ( ) [x 1, x 2, x 3, x 4, x 5 ] = x 1 (foldr1 ( ) [x 2, x 3, x 4, x 5 ])

FP 2005 3.240 408 foldr1 foldr1 foldr1 ( ) [x] :: (a -> a -> a) -> [a] -> a = x foldr1 ( ) (x:xs) = x (foldr1 ( ) xs) foldr1 ( ) [x 1, x 2, x 3, x 4, x 5 ] = x 1 (foldr1 ( ) [x 2, x 3, x 4, x 5 ]) = x 1 (x 2 (foldr1 ( ) [x 3, x 4, x 5 ]))

FP 2005 3.241 409 foldr1 foldr1 foldr1 ( ) [x] :: (a -> a -> a) -> [a] -> a = x foldr1 ( ) (x:xs) = x (foldr1 ( ) xs) foldr1 ( ) [x 1, x 2, x 3, x 4, x 5 ] = x 1 (foldr1 ( ) [x 2, x 3, x 4, x 5 ]) = x 1 (x 2 (foldr1 ( ) [x 3, x 4, x 5 ])) = x 1 (x 2 (x 3 (foldr1 ( ) [x 4, x 5 ])))

FP 2005 3.242 410 foldr1 foldr1 foldr1 ( ) [x] :: (a -> a -> a) -> [a] -> a = x foldr1 ( ) (x:xs) = x (foldr1 ( ) xs) foldr1 ( ) [x 1, x 2, x 3, x 4, x 5 ] = x 1 (foldr1 ( ) [x 2, x 3, x 4, x 5 ]) = x 1 (x 2 (foldr1 ( ) [x 3, x 4, x 5 ])) = x 1 (x 2 (x 3 (foldr1 ( ) [x 4, x 5 ]))) = x 1 (x 2 (x 3 (x 4 (foldr1 ( ) [x 5 ]))))

FP 2005 3.243 411 foldr1 foldr1 foldr1 ( ) [x] :: (a -> a -> a) -> [a] -> a = x foldr1 ( ) (x:xs) = x (foldr1 ( ) xs) foldr1 ( ) [x 1, x 2, x 3, x 4, x 5 ] = x 1 (foldr1 ( ) [x 2, x 3, x 4, x 5 ]) = x 1 (x 2 (foldr1 ( ) [x 3, x 4, x 5 ])) = x 1 (x 2 (x 3 (foldr1 ( ) [x 4, x 5 ]))) = x 1 (x 2 (x 3 (x 4 (foldr1 ( ) [x 5 ])))) = x 1 (x 2 (x 3 (x 4 x 5 )))

FP 2005 3.244 412 foldr foldr :: (a -> b -> b) -> b -> [a] -> b foldr ( ) z [] = z foldr ( ) z (x:xs) = x (foldr ( ) z xs)

FP 2005 3.245 413 foldrx foldrx :: ( a b b ) b [ a ] b foldrx ( ) z [ ] = z foldrx ( ) z ( x : xs ) = x ( foldrx ( ) z xs )

FP 2005 3.246 414 foldr foldr :: (a -> b -> b) -> b -> [a] -> b foldr ( ) z [] = z foldr ( ) z (x:xs) = x (foldr ( ) z xs) foldr ( ) z [x 1, x 2, x 3, x 4, x 5 ]

FP 2005 3.247 415 foldr foldr :: (a -> b -> b) -> b -> [a] -> b foldr ( ) z [] = z foldr ( ) z (x:xs) = x (foldr ( ) z xs) foldr ( ) z [x 1, x 2, x 3, x 4, x 5 ] = x 1 (foldr ( ) z [x 2, x 3, x 4, x 5 ])

FP 2005 3.248 416 foldr foldr :: (a -> b -> b) -> b -> [a] -> b foldr ( ) z [] = z foldr ( ) z (x:xs) = x (foldr ( ) z xs) foldr ( ) z [x 1, x 2, x 3, x 4, x 5 ] = x 1 (foldr ( ) z [x 2, x 3, x 4, x 5 ]) = x 1 (x 2 (foldr ( ) z [x 3, x 4, x 5 ]))

FP 2005 3.249 417 foldr foldr :: (a -> b -> b) -> b -> [a] -> b foldr ( ) z [] = z foldr ( ) z (x:xs) = x (foldr ( ) z xs) foldr ( ) z [x 1, x 2, x 3, x 4, x 5 ] = x 1 (foldr ( ) z [x 2, x 3, x 4, x 5 ]) = x 1 (x 2 (foldr ( ) z [x 3, x 4, x 5 ])) = x 1 (x 2 (x 3 (foldr ( ) z [x 4, x 5 ])))

FP 2005 3.250 418 foldr foldr :: (a -> b -> b) -> b -> [a] -> b foldr ( ) z [] = z foldr ( ) z (x:xs) = x (foldr ( ) z xs) foldr ( ) z [x 1, x 2, x 3, x 4, x 5 ] = x 1 (foldr ( ) z [x 2, x 3, x 4, x 5 ]) = x 1 (x 2 (foldr ( ) z [x 3, x 4, x 5 ])) = x 1 (x 2 (x 3 (foldr ( ) z [x 4, x 5 ]))) = x 1 (x 2 (x 3 (x 4 (foldr ( ) z [x 5 ]))))

FP 2005 3.251 419 foldr foldr :: (a -> b -> b) -> b -> [a] -> b foldr ( ) z [] = z foldr ( ) z (x:xs) = x (foldr ( ) z xs) foldr ( ) z [x 1, x 2, x 3, x 4, x 5 ] = x 1 (foldr ( ) z [x 2, x 3, x 4, x 5 ]) = x 1 (x 2 (foldr ( ) z [x 3, x 4, x 5 ])) = x 1 (x 2 (x 3 (foldr ( ) z [x 4, x 5 ]))) = x 1 (x 2 (x 3 (x 4 (foldr ( ) z [x 5 ])))) = x 1 (x 2 (x 3 (x 4 (x 5 (foldr ( ) z [])))))

FP 2005 3.252 420 foldr foldr :: (a -> b -> b) -> b -> [a] -> b foldr ( ) z [] = z foldr ( ) z (x:xs) = x (foldr ( ) z xs) foldr ( ) z [x 1, x 2, x 3, x 4, x 5 ] = x 1 (foldr ( ) z [x 2, x 3, x 4, x 5 ]) = x 1 (x 2 (foldr ( ) z [x 3, x 4, x 5 ])) = x 1 (x 2 (x 3 (foldr ( ) z [x 4, x 5 ]))) = x 1 (x 2 (x 3 (x 4 (foldr ( ) z [x 5 ])))) = x 1 (x 2 (x 3 (x 4 (x 5 (foldr ( ) z []))))) = x 1 (x 2 (x 3 (x 4 (x 5 z))))

FP 2005 3.253 421 List Folding foldr foldr f z [] foldr f z (x:xs) foldr1 foldr1 f [x] foldr1 f (x:xs) foldl foldl f z [] foldl f z (x:xs) foldl1 foldl1 f (x:xs) :: (a -> b -> b) -> b -> [a] -> b = z = f x (foldr f z xs) :: (a -> a -> a) -> [a] -> a = x = f x (foldr1 f xs) :: (a -> b -> a) -> a -> [b] -> a = z = foldl f (f z x) xs :: (a -> a -> a) -> [a] -> a = foldl f x xs

FP 2005 3.254 422 A simple definition: limit = 10 ^ 2 Unfolding Definitions

FP 2005 3.255 423 A simple definition: limit = 10 ^ 2 Expanding this definition: 4 ( limit + 1) Unfolding Definitions

FP 2005 3.256 424 A simple definition: limit = 10 ^ 2 Expanding this definition: 4 * (limit + 1) = 4 * ((10 ^ 2) + 1) Unfolding Definitions

FP 2005 3.257 425 A simple definition: limit = 10 ^ 2 Expanding this definition: 4 * (limit + 1) = 4 * ((10 ^ 2) + 1) = Unfolding Definitions

FP 2005 3.258 426 A simple definition: limit = 10 ^ 2 Expanding this definition: 4 * (limit + 1) = 4 * ((10 ^ 2) + 1) = Unfolding Definitions Another definition: concat = foldr ( ++ ) [ ]

FP 2005 3.259 427 A simple definition: limit = 10 ^ 2 Expanding this definition: 4 * (limit + 1) = 4 * ((10 ^ 2) + 1) = Unfolding Definitions Another definition: concat = foldr ( ++ ) [ ] Expanding this definition: concat [ [1,2,3], [4,5] ]

FP 2005 3.260 428 A simple definition: limit = 10 ^ 2 Expanding this definition: 4 * (limit + 1) = 4 * ((10 ^ 2) + 1) = Unfolding Definitions Another definition: concat = foldr ( ++ ) [ ] Expanding this definition: concat [ [1,2,3], [4,5] ] = ( foldr ( ++ ) [ ] ) [ [1,2,3], [4,5] ] =

FP 2005 3.261 429 Enumeration Type Definitions data Bool = False True deriving ( Eq, Ord, Read, Show ) data Ordering = LT EQ GT deriving ( Eq, Ord, Read, Show ) data Suit = Diamonds Hearts Spades Clubs deriving ( Eq, Ord ) Pattern matching: not False = True not True = False lexicalcombineordering :: Ordering Ordering Ordering lexicalcombineordering LT _ = LT lexicalcombineordering EQ x = x lexicalcombineordering GT _ = GT

FP 2005 3.262 430 Simple data Type Definitions data Point = Pt Int Int deriving ( Eq ) screen coordinates data Transport = Feet Bike Train Int price in cent This defines at the same time data constructors: Pt :: Int Int Point Feet :: Transport Bike :: Transport Train :: Int Transport Pattern matching: addpt ( Pt x1 y1) ( Pt x2 y2 ) = Pt ( x1 + x2 ) ( y1 + y2 ) cost Feet = 0 cost Bike = 0 cost ( Train Int ) = Int

FP 2005 3.263 431 Simple Polymorphic data Type Definitions The prelude type constructors Maybe, Either, Complex are defined as follows: data Maybe a = Nothing Just a deriving ( Eq, Ord, Read, Show ) data Either a b = Left a Right b data Complex r = r :+ r deriving ( Eq, Read, Show ) This defines at the same time data constructors: Nothing :: Maybe a Just :: a Maybe a Left :: a Either a b Right :: b Either a b ( :+ ) :: r r Complex r