EINDHOVEN

tue

UNIVERSITY

OF

TECHNOLOGY

Department

of

Mathematics

and

Computing

Science

Graduating

Dissertation

Implementing

Elements

of

the

Spec-Calculus

by

H.T.G.

Weffers

Supervisor

Prof.dr

R.C.

Backhouse

August

Trademarks

Throughout

this

document

trademarked

names

may

be

used

Rather

than

put

a

trademark

symbol

in

every

occurrence

of

a

trademarked

name

we

state

that

we

are

using

the

names

only

in

an

editorial

fashion

and

to

the

benefit

of

the

trademark

owner

with

no

intention

of

infringement

of

the

trademark

The

critical

attitude

may

be

described

as

the

conscious

attempt

to

make

our

theories

our

conjectures

suffer

in

our

stead

in

the

struggle

for

the

survival

of

the

fittest

It

gives

us

a

chance

to

survive

the

elimination

of

an

inadequate

-LCB-

when

a

more

dogmatic

attitude

would

eliminate

it

by

eliminating

us

Sir

Karl

Popper

We

zouden

ons

daarom

moeten

inspannen

om

aan

het

publiek

het

wetenschappelijk

succes

zichtbaar

te

maken

Prof.dr.ir

Ackermans

at

lustral

symposium

ECMI

Postgraduate

Programme

Mathematics

for

Industry

Abstract

The

spec-calculus

is

a

programming

algebra

which

is

based

on

a

relational

calculus

It

has

been

developed

with

the

goal

of

deriving

programs

in

a

concise

and

elegant

manner

In

practice

programs

also

ought

to

be

implementable

In

this

report

we

discuss

some

issues

related

to

the

implementation

of

expressions

from

the

spec-calculus

and

some

problems

that

arise

when

implementing

these

expressions

in

a

functional

programming

language

We

aim

for

implementations

that

have

a

maximal

resemblance

to

the

spec-expressions

whilst

using

methods

and

techniques

that

are

used

by

functional

programmers

In

particular

we

investigate

the

implementations

of

relators

functional

catamorphisms

and

witnesses

to

isomorphisms

The

calculations

and

proofs

in

this

report

are

done

step-by-step

This

way

the

derivations

and

proofs

may

also

be

verified

by

people

who

are

not

fluent

with

the

spec-calculus

Contents

Preface

iii

Acknowledgements

v

Introduction

Relators

Datatypes

and

Polymorphism

Relators

in

the

Spec-Calculus

Implementing

Relators

Implementing

unary

map

relators

Implementing

composite

relators

Implementing

relators

in

general

Equality

vs.

Isomorphism

Summary

Exercises

Calculating

Functions

Catamorphisms

Implementing

Catamorphisms

Monad

Decomposition

Exemplified

Summary

Exercises

Calculating

Isomorphisms

Isomorphisms

in

the

Spec-Calculus

List

Isomorphisms

Reverse

A

swap-free

isomorphism

i

A

Class

of

Isomorphisms

Summary

Exercises

Discussion

Conclusions

and

Suggestions

for

Further

Research

A

Datatypes

and

Polymorphism

in

Gofer

A.

Datatypes

A.

Type

synonyms

A.

Polymorphism

A.

Overloading

revisited

B

Solutions

to

Selected

Exercises

B.

Solution

to

Exercise

B.

Solution

to

Exercise

B.

Solution

to

Exercise

B.

Solution

to

Exercise

B.

Solution

to

Exercise

B.

Solution

to

Exercise

C

Additional

Theorems

Bibliography

Index

Name

Index

ii

Preface

Life

is

full

of

untapped

sources

of

pleasure

Education

should

train

us

to

discover

and

exploit

them

N.

Douglas

An

Almanac

This

thesis

presents

some

of

the

results

of

the

research

I

have

done

during

the

past

year

under

supervision

of

prof.dr

R.C.

Backhouse

at

the

Department

of

Mathematics

and

Computing

Science

of

the

Eindhoven

University

of

Technology

In

September

we

set

out

to

investigate

the

possibilities

for

the

implementation

of

a

program

that

could

automatically

translate

spec-expressions

into

program

segments

written

in

a

functional

programming

language

After

a

while

it

turned

out

that

a

possible

implementation

would

be

much

more

difficult

than

we

had

at

first

expected

We

then

changed

our

research

objective

Instead

of

writing

a

program

to

translate

the

specexpressions

we

agreed

on

doing

some

research

on

how

to

implement

the

spec-expressions

in

a

functional

programming

language

The

idea

was

to

write

a

report

in

which

we

would

demonstrate

to

the

reader

how

they

could

do

such

translations

themself

The

underlying

report

contains

a

fair

representation

of

the

results

we

have

obtained

thus

far

H.T.G.

Weffers

Eindhoven

-LCB-

August

iii

iv

Acknowledgements

Writing

is

one

of

the

few

professions

left

where

you

take

all

the

responsibility

for

what

you

do

E.

Jong

The

craft

of

poetry

Listing

the

author

's

name

on

the

spine

of

a

book

is

like

listing

the

quarterback

of

a

football

team

Writing

and

producing

a

book

is

a

team

effort

Mark

Forbes

Writing

Technical

Articles

Speeches

and

Manuals

The

results

in

this

report

and

the

report

itself

have

been

shaped

by

many

people

Their

contributions

range

from

brief

comments

or

remarks

to

extensive

detailed

criticisms

and

suggestions

they

deserve

much

of

the

credit

for

the

evolution

of

the

report

toward

its

present

form

and

content

I

do

however

claim

all

blame

for

its

remaining

failings

First

and

foremost

I

would

like

to

thank

Roland

Backhouse

for

his

constant

encouragement

his

crucial

guidance

and

the

many

pleasant

hours

of

tutoring

I

would

also

like

to

express

my

gratitude

to

Mark

P.

Jones

and

Luc

Duponcheel

for

their

help

on

the

understanding

and

use

of

type

classes

and

constructor

classes

in

general

and

in

Gofer

in

particular

Furthermore

I

would

like

to

thank

Henk

Doornbos

Paul

Hoogendijk

Ed

Voermans

Bart

Gijsen

and

Ed

Knapen

Finally

I

also

would

like

to

take

this

opportunity

to

thank

my

parents

for

their

support

during

all

of

my

years

at

the

university

and

especially

for

their

patience

during

the

past

year

v

It

is

always

exciting

and

fruitful

when

two

disparate

scientific

fields

are

found

to

have

much

in

common

Each

field

is

enriched

by

the

different

perspective

and

insights

of

the

other

Walters

-LSB-

-RSB-

Chapter

Introduction

Motivation

In

his

inaugural

speech

at

the

University

of

Oxford

C.A.R.

Hoare

stressed

that

programming

is

a

mathematical

activity

He

said

Programming

is

a

mathematical

activity

Like

other

branches

of

applied

mathematics

and

engineering

its

successful

practice

requires

determined

and

meticulous

application

of

traditional

methods

of

mathematical

understanding

calculation

and

proof

One

approach

to

programming

as

a

mathematical

activity

is

by

means

of

the

spec-calculus

Over

the

last

few

years

R.C.

Backhouse

and

his

colleagues

have

been

developing

a

theory

of

datatypes

based

on

a

point-free

axiomatisation

of

the

calculus

of

relations

-LRB-

cf.

-LSB-

-RSB-

-RRB-

The

primary

goal

of

this

research

has

been

to

develop

an

algebra

that

expedites

the

calculation

of

programs

manipulating

non-trivial

datatypes

Conciseness

and

elegance

of

the

formulated

laws

has

always

been

a

major

desideratum

of

the

algebra

The

spec-calculus

which

forms

the

basis

of

their

work

is

a

programming

algebra

in

which

programs

are

parameterised

by

arbitrary

datatypes

This

means

that

properties

can

be

derived

that

hold

for

all

datatypes

and

that

programs

can

be

constructed

that

do

not

depend

on

the

types

of

the

arguments

to

which

these

programs

are

applied

These

programs

all

exhibit

a

truly

polymorphic

behaviour

Often

however

a

program

in

a

mathematical

framework

is

not

enough

and

we

need

or

want

an

implementation

of

the

program

such

that

it

can

be

executed

by

a

computer

If

we

want

elements

from

the

spec-calculus

to

be

implemented

we

would

really

need

a

relational

programming

language

e.g.

Ruby

-LRB-

cf.

-LSB-

-RSB-

-LSB-

-RSB-

-RRB-

These

languages

however

are

not

yet

widespread

and

still

in

development

Are

there

any

alternatives

The

spec-calculus

has

a

lot

of

notions

in

common

with

the

category

theory

which

is

an

algebra

of

functions

-LRB-

cf.

-LSB-

-RSB-

-RRB-

Since

these

categorical

notions

are

based

on

functions

they

should

be

implementable

in

a

functional

programming

language

Introduction

Functional

programming

-LRB-

cf.

-LSB-

-RSB-

-RRB-

uses

a

descriptive

programming

formula

which

suggests

that

the

functional

programming

style

should

be

an

ideal

way

of

specifying

data

structures

This

is

indeed

one

of

the

areas

of

application

where

this

method

of

programming

excels

Because

of

its

very

nature

functional

programming

is

also

good

at

describing

functions

on

data

structures

such

as

searches

which

extract

information

from

them

and

functions

-LRB-

called

maps

-RRB-

which

copy

whole

structures

applying

a

function

to

every

sub-structure

to

specify

a

new

structure

The

fact

that

the

programs

in

the

spec-calculus

are

constructed

using

relations

and

that

these

programs

are

truly

polymorphic

however

gives

rise

to

a

number

of

problems

when

trying

to

implement

them

in

an

existing

functional

programming

language

Even

if

we

restrict

ourselves

to

functional

spec-expressions

we

will

still

have

some

problems

implementing

these

expressions

due

to

the

restricted

possibilities

of

polymorphism

in

functional

programming

languages

Since

types

in

a

functional

programming

language

are

not

first-class

citizens

they

can

not

be

passed

to

functions

as

parameters

This

implies

that

we

can

not

implement

the

spec-expressions

that

are

parameterised

over

datatypes

directly

If

we

want

to

construct

a

polymorphic

implementation

we

will

have

to

construct

this

implementation

using

type

classes

or

constructor

classes

-LRB-

cf.

-LSB-

-RSB-

-RRB-

But

even

this

powerful

mechanism

is

not

sufficient

to

implement

general

polymorphic

functions

The

type

class

and

constructor

class

mechanism

only

suffices

when

we

can

identify

a

general

typing

for

the

elements

of

the

class

of

functions

that

we

want

to

capture

with

the

type

class

or

the

class

of

type

constructors

we

want

to

capture

with

the

constructor

class

Another

problem

is

that

in

the

spec-calculus

types

can

be

really

equal

whilst

in

functional

programming

types

can

only

be

equal

up

to

isomorphism

This

means

that

explicit

coercion

functions

between

types

in

a

functional

programming

language

always

have

to

exist

In

this

report

we

address

some

of

the

problems

that

arise

when

trying

to

implement

specexpressions

in

a

functional

programming

language

In

fact

in

this

report

we

are

going

to

take

a

look

at

only

a

small

part

of

the

spec-calculus

and

we

are

going

to

describe

how

to

implement

spec-calculus

expressions

as

program

segments

written

in

the

functional

programming

language

Gofer

-LRB-

cf.

-LSB-

-RSB-

-RRB-

In

particular

we

are

going

to

investigate

relators

functional

catamorphisms

and

witnesses

to

isomorphisms

We

will

calculate

the

spec-expressions

stepby-step

in

small

steps

-LRB-

where

possible

-RRB-

so

that

even

readers

who

are

not

fluent

with

the

spec-calculus

may

easily

verify

the

proofs

and

derivations

In

this

report

we

are

interested

in

polymorphic

implementations

that

bear

a

maximal

resemblance

to

the

spec-expressions

and

which

can

be

implemented

using

methods

that

a

real

functional

programmer

would

use

We

are

not

concerned

with

efficiency

issues

since

techniques

like

transformational

programming

may

be

used

to

transform

correct

but

possibly

inefficient

programs

to

correct

and

efficient

solutions

using

semantics-preserving

transformations

The

spec-calculus

has

a

lot

of

notions

in

common

with

category

theory

lattice

theory

and

regular

algebra

In

literature

we

may

find

a

plethora

of

books

articles

and

papers

published

on

subjects

within

these

research

areas

With

respect

to

implementing

some

of

these

notions

we

may

find

some

related

work

in

-LSB-

-RSB-

-LSB-

-RSB-

and

-LSB-

-RSB-

It

is

always

exciting

when

two

disparate

scientific

fields

are

found

to

have

much

in

common

Each

field

is

enriched

by

the

different

perspectives

and

insights

of

the

other

Introduction

Introduction

Why

Gofer

As

already

indicated

we

will

be

using

the

functional

programming

language

Gofer

-LRB-

cf.

-LSB-

-RSB-

-LSB-

-RSB-

-RRB-

Gofer

is

only

one

of

many

functional

programming

languages

that

are

available

nowadays

We

chose

Gofer

over

Haskell

Miranda

ML

and

other

functional

programming

languages

because

it

has

several

very

pleasant

features

Since

Gofer

is

a

Haskell

dialect

it

has

the

advantages

-LRB-

cf.

-LSB-

-RSB-

-RRB-

of

ffl

being

freely

available

ffl

being

suitable

for

teaching

research

and

applications

including

building

large

systems

ffl

being

completely

described

via

the

publication

of

a

formal

syntax

and

semantics

-LRB-

cf.

-LSB-

-RSB-

-LSB-

H

-RSB-

-RRB-

ffl

being

based

on

ideas

that

enjoy

a

wide

consensus

ffl

reducing

unnecessary

diversity

in

functional

programming

languages

However

Gofer

is

not

merely

a

subset

of

Haskell

In

Gofer

we

also

find

several

experimental

features

-LRB-

cf.

-LSB-

-RSB-

-LSB-

-RSB-

-RRB-

that

we

can

use

to

our

advantage

quite

extensively

in

the

programs

that

we

are

going

to

construct

in

this

report

Overview

This

report

is

not

self-contained

We

take

for

granted

that

the

reader

has

some

knowledge

of

the

spec-calculus

as

it

is

presented

in

-LSB-

-RSB-

and

that

he/she

is

familiar

with

the

algebraic

framework

as

well

as

with

the

relational

model

of

the

spec-calculus

In

Chapter

we

take

a

look

at

the

notion

of

relator

and

at

the

implementation

of

relators

These

relators

are

the

major

building

blocks

of

programs

since

they

can

be

associated

with

the

notion

of

datatypes

A

program

does

not

only

contain

datatypes

but

also

functions

defined

over

these

datatypes

In

Chapter

we

therefore

consider

the

functional

catamorphisms

These

functional

catamorphisms

are

the

spec-calculus

counterparts

of

a

class

of

functions

which

are

defined

using

simple

structural

recursion

We

will

demonstrate

calculations

of

and

calculations

with

these

catamorphisms

using

a

specific

example

One

important

issue

in

the

spec-calculus

is

the

notion

of

isomorphism

In

Chapter

we

consider

the

calculations

of

and

calculations

with

isomorphisms

in

closer

detail

As

an

example

we

take

the

datatypes

cons-list

and

snoc-list

and

we

derive

two

isomorphisms

between

these

two

datatypes

The

derivations

are

done

using

the

spec-calculus

In

Chapter

we

present

a

method

of

implementing

spec-expressions

which

is

different

from

the

one

discussed

in

the

previous

chapters

This

method

is

quite

heavily

used

by

people

who

are

experienced

in

category

theory

and

spec-calculus

In

contrast

to

the

method

described

in

previous

chapters

this

method

uses

only

one

single

datatype

to

represent

the

entire

speccalculus

With

this

approach

all

typing

problems

are

gone

but

also

all

datatypes

as

we

know

them

Introduction

Introduction

In

Chapter

we

present

some

conclusions

with

respect

to

the

applicability

of

functional

programming

languages

as

an

implementation

language

for

spec-expressions

We

also

give

some

suggestions

for

future

research

Appendix

A

presents

a

short

introduction

to

the

notion

of

datatypes

type

classes

and

constructor

classes

in

Gofer

Readers

who

are

not

familiar

with

these

concepts

are

advised

to

first

read

this

appendix

since

these

concepts

are

of

vital

importance

to

the

implementation

of

polymorphic

functions

throughout

this

report

For

a

more

expository

introduction

to

the

subjects

in

this

appendix

the

reader

is

referred

to

-LSB-

-RSB-

-LSB-

-RSB-

and

-LSB-

-RSB-

Some

small

parts

of

this

appendix

are

taken

verbatim

from

these

publications

At

the

end

of

Chapter

Chapter

and

Chapter

there

are

some

exercises

for

the

reader

We

encourage

the

reader

to

try

and

do

the

exercises

themself

In

Appendix

B

we

present

some

solutions

to

the

exercises

that

are

marked

with

an

-LRB-

-RRB-

Finally

in

Appendix

C

we

present

some

theorems

along

with

their

proofs

that

are

not

trivial

and

yet

not

to

be

found

in

-LSB-

-RSB-

or

-LSB-

-RSB-

These

theorems

and

their

proofs

are

only

included

for

the

convenience

of

the

reader

Introduction

Chapter

Relators

Datatypes

and

Polymorphism

In

this

chapter

we

investigate

the

implementation

of

relators

Relators

may

be

associated

with

the

notion

of

datatypes

in

functional

programming

We

first

discuss

the

definition

of

a

relator

in

the

spec-calculus

After

that

we

consider

the

implementation

of

relators

We

find

that

there

are

in

general

several

problems

with

respect

to

implementing

polymorphic

functions

over

different

relators

Relators

in

the

Spec-Calculus

General

Definition

In

categorical

approaches

to

type

theory

a

parallel

is

drawn

between

the

notion

of

type

constructor

and

the

categorical

notion

of

functor

-LRB-

cf.

-LSB-

-RSB-

-RRB-

thereby

emphasising

that

a

type

constructor

is

not

just

a

function

from

types

to

types

but

also

comes

equipped

with

a

function

that

maps

morphisms

to

morphisms

i.e.

functions

to

functions

In

the

spec-calculus

a

relator

is

only

a

modest

extension

to

the

notion

of

functor

-LRB-

cf.

-LSB-

-RSB-

-RRB-

In

fact

in

-LSB-

-RSB-

Richard

Bird

and

Oege

de

Moor

demonstrated

that

all

monotonic

functors

are

relators

In

category

theory

and

the

spec-calculus

both

the

function

from

types

to

types

and

the

function

that

maps

morphisms

to

morphisms

are

denoted

by

the

same

symbols

Definition

-LRB-

Relator

-RRB-

A

relator

is

a

function

F

A

A

from

specs

to

specs

such

that

a.

I

w

F

I

b.

F

R

w

F

S

-LRB-

R

w

S

c.

F

-LRB-

RffiS

-RRB-

F

R

ffi

F

S

d.

F

-LRB-

R

-LSB-

-RRB-

-LRB-

F

R

-RRB-

-LSB-

Relators

in

the

Spec-Calculus

The

above

clearly

defines

an

endorelator

i.e.

a

unary

relator

from

a

given

spec

algebra

A

to

itself

But

we

also

wish

to

allow

it

to

serve

as

the

definition

of

a

relator

mapping

specs

from

one

algebra

A

say

into

another

B

say

One

case

that

we

make

particular

use

of

is

when

F

maps

a

pair

of

specs

into

a

spec

We

refer

to

such

relators

as

binary

relators

and

choose

to

denote

them

by

infix

operators

Thus

if

denotes

a

binary

relator

its

defining

properties

would

be

a.

I

w

I

I

b.

R

U

w

S

V

-LRB-

R

w

S

U

w

V

c.

-LRB-

R

ffi

S

-RRB-

-LRB-

U

ffi

V

-RRB-

-LRB-

R

U

-RRB-

ffi

-LRB-

S

V

-RRB-

d.

-LRB-

R

-LSB-

-RRB-

-LRB-

S

-LSB-

-RRB-

-LRB-

R

S

-RRB-

-LSB-

Note

that

our

notion

of

relator

is

very

different

from

the

notion

of

relator

as

it

is

defined

by

Samson

Abramsky

and

Thomas

Jensen

in

-LSB-

-RSB-

In

their

definition

a

relator

need

not

be

composition

preserving

i.e.

part

c.

of

our

definition

need

not

hold

for

their

relators

Sum

relators

An

interesting

class

of

relators

are

the

so-called

sum

relators

F

is

a

sum

relator

if

and

only

if

for

some

relators

G

and

H

and

for

all

specs

X

F

X

G

X

H

X

In

words

F

is

the

lifted

sum

-LRB-

-RRB-

of

G

and

H

The

class

of

sum

relators

is

very

broad

but

in

spite

of

its

generality

there

is

surprisingly

much

to

say

about

the

class

The

most

important

aspect

of

such

a

relator

F

is

that

the

constructors

of

F

can

be

identified

where

F

denotes

the

least

fixed

point

of

the

monotonic

endofunction

F

Theorem

-LRB-

Constructors

-RRB-

For

relators

F

G

and

H

such

that

F

G

H

F

o

F

F

where

o

F

ffi

G

F

F

ffi

F

ffi

H

F

F

ffi

If

it

is

clear

from

the

context

which

relator

we

are

working

with

we

will

omit

the

subscripts

and

simply

write

o

and

A

paraphrase

of

this

theorem

might

be

that

all

elements

of

F

are

constructed

by

injections

of

elements

of

G

F

or

elements

of

H

F.

For

this

reason

we

call

o

and

the

constructors

of

F.

Relators

Datatypes

and

Polymorphism

Relators

in

the

Spec-Calculus

Partial

application

If

we

take

a

binary

relator

and

a

fixed

spec

R

we

can

apply

to

R

The

result

is

the

monotonic

function

R

or

the

monotonic

function

R

If

fact

R

-LRB-

X

R

X

-RRB-

and

R

-LRB-

X

X

R

-RRB-

For

brevity

we

often

use

square

brackets

to

denote

abstraction

with

respect

to

spec-valued

variables

in

a

formula

For

example

we

write

-LSB-

X

-RSB-

to

denote

the

relator

-LRB-

X

X

-RRB-

When

the

enclosed

formula

contains

more

than

one

free

variable

the

square

bracket

notation

denotes

abstraction

in

alphabetic

order

Thus

-LSB-

R

X?X

-RSB-

denotes

the

binary

function

-LRB-

R

-LRB-

X

R

X?X

-RRB-

-RRB-

and

is

different

from

-LSB-

X

R?R

-RSB-

which

denotes

the

function

-LRB-

R

-LRB-

X

X

R?R

-RRB-

-RRB-

Consequently

we

can

write

R

as

-LSB-

R

X

-RSB-

If

we

take

the

least

fixed

point

of

the

-LRB-

unary

-RRB-

monotonic

function

R

we

get

the

spec

-LRB-

R

-RRB-

If

R

is

a

monotype

then

-LRB-

R

-RRB-

is

a

monotype

that

is

-LRB-

R

-RRB-

v

I

An

example

of

such

a

monotype

is

Nat

-LSB-

X

-RSB-

Map

relators

If

we

now

abstract

from

the

spec

R

in

-LRB-

R

-RRB-

we

get

the

function

-LRB-

R

-LRB-

R

-RRB-

-RRB-

This

function

is

a

unary

relator

Relators

that

are

constructed

in

this

way

are

called

map

relators

Examples

of

map

relators

are

List

R

-LSB-

R?X

-RSB-

Tree

R

-LSB-

R

X?X

-RSB-

With

each

map

relator

V

such

that

V

R

-LSB-

R

X

-RSB-

we

may

associate

a

relator

I

We

will

call

this

relator

the

initial

relator

of

V

and

denote

it

by

V.

Specifically

if

V

R

-LSB-

R

X

-RSB-

then

V

-LSB-

I

X

-RSB-

One

important

property

is

-LRB-

V

-RRB-

-LSB-

I

X

-RSB-

i.e.

-LRB-

V

-RRB-

V

I

In

fact

the

initial

relator

represents

a

kind

of

primal

structure

that

is

used

to

generate

all

elements

of

a

specific

structure

Grounded

relators

A

typical

characteristic

of

monotypes

occurring

in

programming

problems

is

that

their

elements

are

generated

from

a

base

-LRB-

mono

-RRB-

type

by

application

of

one

or

more

operations

Polymorphic

types

such

as

list

or

tree

are

families

of

monotypes

parameterised

by

some

base

-LRB-

mono

-RRB-

type

We

call

such

types

polymorphically

grounded

types

or

rather

we

call

their

defining

relators

polymorphically

grounded

the

word

grounded

referring

to

the

existence

of

a

base

-LRB-

mono

-RRB-

type

The

mechanism

needed

to

introduce

the

notion

of

a

grounded

monotype

into

our

class

of

relators

is

straightforward

we

consider

a

sum

relator

and

choose

the

left

component

of

the

sum

to

be

a

constant

relator

If

this

constant

relator

is

the

unit

type

then

we

call

this

grounded

relator

a

pointed

relator

Relators

Datatypes

and

Polymorphism

Implementing

Relators

Implementing

Relators

Now

that

we

know

what

relators

are

we

consider

their

implementation

When

we

want

to

implement

a

relator

we

have

to

implement

ffl

The

function

from

types

to

types

that

comes

with

the

relator

This

function

may

be

implemented

by

a

type

constructor

which

can

be

-LRB-

recursively

-RRB-

defined

using

a

datadefinition

ffl

The

function

that

maps

morphisms

to

morphisms

i.e.

functions

to

functions

This

function

corresponds

to

the

map

function

in

functional

programming

This

map

function

is

recursively

defined

over

the

corresponding

datatype

ffl

If

the

relator

is

a

sum

relator

then

we

also

have

to

implement

the

constructors

of

the

relator

The

constructors

of

a

relator

can

be

implemented

by

the

constructor

functions

that

are

implicitly

defined

in

a

data-definition

We

want

to

stress

in

advance

that

we

aim

for

polymorphic

implementations

so

that

we

can

implement

and

use

more

than

one

relator

in

our

programs

In

the

functional

programming

language

Gofer

there

are

three

possibilities

for

implementing

a

polymorphic

function

-LRB-

see

Appendix

A

-RRB-

ffl

If

we

define

a

new

type

constructor

using

a

data-definition

then

we

actually

define

a

parametric

polymorphic

type

constructor

ffl

Using

type

classes

we

can

implement

normal

-LRB-

higher-order

-RRB-

functions

with

a

parametric

polymorphic

behaviour

ffl

Using

constructor

classes

we

can

implement

functions

that

have

to

exhibit

ad-hoc

polymorphic

behaviour

Especially

functions

that

are

to

be

recursively

defined

over

data

structures

exhibit

this

kind

of

behaviour

In

the

remainder

of

this

chapter

we

demonstrate

how

to

implement

several

kinds

of

relators

We

consider

the

implementations

of

the

following

kinds

of

relators

ffl

Unary

map

relators

We

demonstrate

how

to

implement

a

unary

map

relator

by

showing

in

detail

how

to

implement

the

unary

map

relator

List

which

is

defined

by

List

R

-LSB-

R?X

-RSB-

ffl

Composite

relators

A

composite

relator

is

a

relator

that

is

explicitly

defined

in

terms

of

other

relators

We

consider

the

relator

RoseTree

which

is

defined

by

RoseTree

R

-LSB-

R

R?List

X

-RSB-

ffl

Finally

we

consider

the

implementation

of

basic

relators

like

-LRB-

X

I?X

-RRB-

When

we

consider

these

relators

we

will

observe

several

problems

that

arise

when

trying

to

implement

relators

in

general

and

functions

that

are

parameterised

by

relators

Relators

Datatypes

and

Polymorphism

Implementing

Relators

Why

do

we

consider

these

relators

to

be

different

These

kinds

of

relators

are

not

different

in

the

spec-calculus

but

with

respect

to

their

implementations

there

are

several

significant

differences

By

considering

them

independently

we

can

stress

these

differences

In

relating

typed

functional

programming

to

category

theory

we

identify

objects

in

a

category

with

types

and

morphisms

between

objects

with

functions

In

programming

we

meet

not

only

types

and

functions

but

also

type

constructors

-LCB-

things

which

take

types

and

yield

new

types

Corresponding

to

these

type

constructors

is

the

categorical

concept

of

a

functor

Functors

are

not

only

a

transformation

of

types

-LRB-

object

-RRB-

but

also

include

an

accompanying

transformation

of

morphisms

They

turn

out

to

be

therefore

maps

between

categories

-LCB-

David

E.

Rydeheard

-LSB-

-RSB-

Implementing

unary

map

relators

In

this

section

we

present

in

detail

the

implementation

of

the

relator

List

which

is

defined

by

List

R

-LSB-

R?X

-RSB-

The

function

from

types

to

types

Since

we

are

only

interested

in

polymorphic

implementations

we

do

not

want

our

implementation

to

depend

in

any

way

on

the

details

of

any

specific

base

-LRB-

mono

-RRB-

type

Therefore

we

will

consider

List

I

This

means

that

we

are

looking

for

the

least

solution

of

the

equation

X

X

I?X

Using

the

computation

rules

for

we

find

for

the

solution

List

I

List

I

-LRB-

ffi

-RRB-

-LRB-

ffi

I?List

I

-RRB-

Using

a

data-definition

we

may

implement

the

function

from

types

to

types

of

relator

List

by

data

List

a

Nilc

App

-LRB-

a

-RRB-

-LRB-

List

a

-RRB-

By

its

very

nature

a

functional

programming

language

always

results

in

the

least

datatype

i.e.

an

object

of

type

List

a

is

constructed

out

of

nothing

and

is

Nill

or

it

is

constructed

-LCB-

in

a

finite

number

of

steps

-LCB-

by

applying

App

to

an

element

a

and

another

List

a

and

by

no

other

means

at

all

In

this

implementation

we

can

identify

the

type

constructor

List

the

constructor

function

Nill

and

the

binary

constructor

function

App

The

type

constructor

List

is

the

function

from

types

to

types

If

it

is

applied

to

the

type

Int

which

represents

the

natural

numbers

we

get

the

type

List

Int

which

represents

the

lists

over

the

natural

numbers

Note

that

relators

correspond

to

datatypes

in

functional

programming

-LRB-

e.g.

the

type

constructor

Relators

Datatypes

and

Polymorphism

Implementing

Relators

List

in

combination

with

its

constructor

functions

Nill

and

App

-RRB-

whereas

types

-LRB-

e.g.

Int

and

List

Int

-RRB-

correspond

to

monotypes

Although

the

implementation

seems

quite

straightforward

there

are

a

few

subtle

details

which

deserve

our

attention

In

the

spec-calculus

we

can

identify

the

different

parts

of

a

disjoint-sum

by

means

of

the

tags

and

In

functional

programming

we

do

not

have

such

anonymous

tags

This

implies

that

we

have

to

use

unique

identifiers

like

Nill

and

App

Note

that

the

disjoint

sum

in

functional

programming

corresponds

to

a

and

not

to

the

disjoint

sum

in

the

spec-calculus

i.e.

not

to

a

Although

Gofer

's

is

a

symmetric

and

associative

operator

we

will

consider

it

to

be

an

asymmetric

right-associative

operator

This

makes

the

implementation

of

much

more

straightforward

The

tag

can

be

implemented

by

the

constructor

function

Nill

and

the

tag

can

be

implemented

by

the

constructor

function

App

I?List

I

is

a

kind

of

domain

restriction

and

it

corresponds

to

the

type

of

the

constructor

function

App

Domain

restrictions

can

be

considered

as

a

kind

of

filter

Only

elements

of

the

correct

type

can

pass

through

these

filters

The

-LRB-

effect

of

the

-RRB-

application

of

to

is

implemented

by

the

fact

that

Nill

is

a

constructor

function

We

can

graphically

represent

the

implementation

details

by

List

I

ffi

ffi

-LRB-

I

List

I

-RRB-

data

List

a

Nill

App

-LRB-

a

-RRB-

-LRB-

List

a

-RRB-

We

now

have

defined

a

type

constructor

List

which

implements

the

function

from

types

to

types

that

comes

with

the

relator

List

As

we

can

observe

this

type

constructor

does

indeed

exhibit

parametric

polymorphic

behaviour

If

we

apply

this

type

constructor

to

a

type

then

the

result

is

a

type

in

which

all

elements

have

a

structure

that

may

be

graphically

represented

-LRB-

cf.

-LSB-

-RSB-

-RRB-

by

App

App

App

App

Nill

Relators

Datatypes

and

Polymorphism

Implementing

Relators

We

leave

out

the

elements

at

the

leaves

of

this

tree

to

emphasise

the

fact

that

this

graph

represents

a

class

of

types

Note

that

the

implementation

of

a

relator

is

only

unique

modulo

identifiers

i.e.

there

is

a

large

number

of

-LRB-

isomorphic

-RRB-

implementations

possible

For

example

data

List

a

Nill

App

-LRB-

a

-RRB-

-LRB-

List

a

-RRB-

data

ConsList

a

Nilc

Cons

-LRB-

a

-RRB-

-LRB-

ConsList

a

-RRB-

Both

these

implementations

are

correct

-LRB-

isomorphic

-RRB-

implementations

of

the

function

from

types

to

types

belonging

to

the

relator

List

but

they

are

not

equal

The

map

function

Besides

a

function

from

types

to

types

a

relator

is

also

a

function

that

maps

functions

to

functions

This

function

has

to

be

recursively

defined

over

the

class

of

datatypes

corresponding

to

the

relator

In

the

case

of

the

relator

List

we

can

implement

the

map

function

by

mapList

-LRB-

a

b

-RRB-

-LRB-

List

a

List

b

-RRB-

mapList

f

-LRB-

Nill

-RRB-

Nill

mapList

f

-LRB-

App

v

lv

-RRB-

App

-LRB-

f

v

-RRB-

-LRB-

mapList

f

lv

-RRB-

How

did

we

construct

this

implementation

One

answer

to

this

question

is

that

we

constructed

it

using

conventional

methods

in

functional

programming

There

is

a

second

answer

but

we

will

refrain

from

elucidating

on

the

second

construction

until

in

the

next

chapter

We

have

to

implement

such

a

map

function

for

each

relator

and

each

map

function

has

to

have

a

unique

identifier

Although

this

is

roughly

in

accordance

with

the

situation

in

the

spec-calculus

we

would

prefer

a

more

polymorphic

function

That

is

we

aim

for

a

function

with

-LRB-

ad-hoc

-RRB-

polymorphic

behaviour

that

groups

the

map

functions

for

a

class

of

type

constructors

This

ad-hoc

polymorphism

can

be

implemented

in

Gofer

by

means

of

the

constructor

class

class

Functor

f

where

map

-LRB-

a

b

-RRB-

-LRB-

f

a

f

b

-RRB-

We

call

this

class

Functor

because

the

function

map

satisfies

the

familiar

functor

laws

map

id

id

map

-LRB-

f

g

-RRB-

-LRB-

map

f

map

g

-RRB-

Here

id

is

an

overloaded

identity

function

We

now

can

simply

define

an

instance

of

this

class

for

our

relator

List

by

instance

Functor

List

where

map

f

-LRB-

Nill

-RRB-

Nill

map

f

-LRB-

App

v

lv

-RRB-

App

-LRB-

f

v

-RRB-

-LRB-

map

f

lv

-RRB-

We

can

define

such

instances

for

all

unary

relators

Only

for

unary

relators

Yes

and

no

We

will

return

to

this

subject

when

we

consider

the

implementation

of

relators

in

general

Relators

Datatypes

and

Polymorphism

Implementing

Relators

Constructors

Since

we

have

that

List

R

-LSB-

R?X

-RSB-

we

also

have

that

List

-LSB-

I?X

-RSB-

i.e.

List

X

I?X

From

this

we

may

conclude

that

List

is

a

sum

relator

Each

sum

relator

has

two

constructors

o

List

and

List

such

that

-LRB-

List

-RRB-

o

List

List

From

the

previous

section

we

have

that

o

List

-LRB-

List

-RRB-

ffi

List

-LRB-

List

-RRB-

ffi

For

o

List

we

have

o

List

f

Definition

of

constructors

g

-LRB-

List

-RRB-

ffi

f

-LRB-

List

-RRB-

List

I

g

List

I

ffi

f

Definition

List

I

-LRB-

-RRB-

g

-LRB-

I?List

I

-RRB-

ffi

f

Computation

rules

for

g

ffi

Note

that

we

explicitly

used

the

equality

List

I

I?List

I

at

-LRB-

-RRB-

In

the

spec-calculus

this

is

a

true

equality

We

can

do

a

similar

calculation

for

List

So

the

constructors

of

List

are

given

by

o

List

ffi

and

List

ffi

-LRB-

I?List

I

-RRB-

As

we

have

seen

before

can

we

implement

ffi

and

ffi

-LRB-

I?List

I

-RRB-

by

the

constructor

functions

Nill

and

App

Throughout

the

remainder

of

this

report

we

will

abuse

our

mathematical

notation

and

terminology

by

writing

o

List

and

List

instead

of

o

List

and

List

and

calling

the

constructors

of

List

constructors

of

relator

List

Relators

Datatypes

and

Polymorphism

Implementing

Relators

Summary

Summarising

one

can

say

that

the

implementation

of

a

unary

map

relator

consists

of

three

parts

ffl

A

data-definition

defining

the

type

constructor

which

represents

the

-LRB-

parametric

-RRB-

polymorphic

function

from

types

to

types

ffl

An

instance

of

the

constructor

class

Functor

in

which

we

give

an

implementation

of

the

map

function

Each

instance

of

this

function

represents

a

function

that

maps

functions

to

functions

over

the

class

of

types

that

may

be

associated

with

a

relator

ffl

The

constructors

which

can

be

implemented

by

the

constructor

functions

implicitly

defined

by

the

data-definition

Another

example

Let

us

now

consider

a

somewhat

more

difficult

example

Let

us

consider

the

relator

M

which

is

defined

by

M

R

-LSB-

R

Y

Y

Y

Y

Y

-RSB-

Since

the

disjoint

sum

operator

is

a

binary

and

right-associative

operator

we

have

to

parse

this

equation

as

M

R

-LSB-

R

-LRB-

Y

Y

Y

Y

Y

-RRB-

-RSB-

Since

we

want

a

polymorphic

implementation

we

will

consider

M

I

which

is

defined

by

M

I

-LSB-

I

-LRB-

Y

Y

Y

Y

Y

-RRB-

-RSB-

Consequently

we

have

for

M

I

M

I

I

-LRB-

M

I?M

I

M

I?M

I?M

I

-RRB-

Using

the

computation

rules

for

twice

we

get

M

I

-LRB-

ffi

I

-RRB-

-LRB-

ffi

-LRB-

-LRB-

ffi

-LRB-

M

I?M

I

-RRB-

-RRB-

-LRB-

ffi

-LRB-

M

I?M

I?M

I

-RRB-

-RRB-

-RRB-

-RRB-

Using

associativity

of

ffi

and

fusion

we

get

M

I

-LRB-

ffi

I

-RRB-

-LRB-

ffi

ffi

-LRB-

M

I?M

I

-RRB-

ffi

ffi

-LRB-

M

I?M

I?M

I

-RRB-

-RRB-

Using

that

we

can

implement

the

by

Gofer

's

and

that

we

have

to

implement

the

combinations

of

tags

by

unique

identifiers

we

can

implement

the

function

from

types

to

types

belonging

to

the

relator

M

I

by

the

type

constructor

M

which

is

implemented

by

data

M

a

Om

a

Two

-LRB-

M

a

-RRB-

-LRB-

M

a

-RRB-

Three

-LRB-

M

a

-RRB-

-LRB-

M

a

-RRB-

-LRB-

M

a

-RRB-

Relators

Datatypes

and

Polymorphism

Implementing

Relators

This

implementation

is

not

trivial

Special

interest

deserves

the

implementation

of

the

M

I?M

I?M

I

part

Instead

of

implementing

this

part

by

two

binary

constructor

functions

we

implemented

it

by

the

ternary

constructor

function

Three

Actually

we

implemented

the

ternary

relator

instead

of

the

relator

-LRB-

-RRB-

which

consists

of

two

binary

relators

We

can

graphically

represent

the

implementation

details

by

M

I

ffi

I

-LRB-

ffi

ffi

-LRB-

M

I

M

I

-RRB-

ffi

ffi

-LRB-

M

I

M

I

M

I

-RRB-

-RRB-

data

M

a

Om

a

Two

-LRB-

M

a

-RRB-

-LRB-

M

a

-RRB-

Three

-LRB-

M

a

-RRB-

-LRB-

M

a

-RRB-

-LRB-

M

a

-RRB-

We

have

now

defined

a

-LRB-

parametric

polymorphic

-RRB-

type

constructor

which

implements

the

function

from

types

to

types

that

comes

with

the

relator

M.

Next

we

have

to

implement

the

map

function

belonging

to

the

relator

M

Since

M

is

also

a

unary

map

relator

we

may

implement

this

function

as

an

instance

of

the

type

class

Functor

using

simple

structural

recursion

I.e.

instance

Functor

M

where

map

f

-LRB-

Om

x

-RRB-

Om

-LRB-

f

x

-RRB-

map

f

-LRB-

Two

x

y

-RRB-

Two

-LRB-

map

f

x

-RRB-

-LRB-

map

f

y

-RRB-

map

f

-LRB-

Three

x

y

z

-RRB-

Three

-LRB-

map

f

x

-RRB-

-LRB-

map

f

y

-RRB-

-LRB-

map

f

z

-RRB-

Finally

we

have

to

implement

the

constructors

of

relator

M.

From

the

previous

section

we

know

that

we

can

implement

the

spec-constructors

by

the

constructor

functions

o

M

M

I

ffi

M

M

I

ffi

Using

the

computation

rules

for

the

twice

and

the

definition

of

M

I

we

find

o

M

M

ffi

ffi

ffi

-LRB-

M

I?M

I

-RRB-

M

ffi

ffi

ffi

-LRB-

M

I?M

I?M

I

-RRB-

Thus

the

relator

M

has

three

constructors

These

constructors

can

be

implemented

by

the

constructor

functions

corresponding

to

the

type

constructor

associated

with

M

That

is

we

can

implement

o

M

by

Om

M

ffi

by

Two

and

M

ffi

by

Three

Relators

Datatypes

and

Polymorphism

Implementing

Relators

Implementing

composite

relators

In

the

previous

section

we

discussed

the

implementation

of

the

unary

map

relator

List

which

is

defined

by

List

R

-LSB-

R?X

-RSB-

In

this

section

we

discuss

the

implementation

of

the

unary

map

relator

RoseTree

which

is

defined

by

RoseTree

R

-LSB-

R

R?List

X

-RSB-

Since

the

relator

RoseTree

is

explicitly

defined

in

terms

of

the

relator

List

we

call

the

unary

map

relator

RoseTree

a

composite

relator

If

we

consider

the

implementations

of

the

relators

List

and

M

we

might

be

tempted

to

implement

the

relator

RoseTree

by

data

RoseTree

a

Bud

a

Rose

-LRB-

a

-RRB-

-LRB-

List

-LRB-

RoseTree

a

-RRB-

-RRB-

mapRT

-LRB-

a

b

-RRB-

-LRB-

RoseTree

a

RoseTree

b

-RRB-

mapRT

f

-LRB-

Bud

x

-RRB-

Bud

-LRB-

f

x

-RRB-

mapRT

f

-LRB-

Rose

x

xs

-RRB-

Rose

-LRB-

f

x

-RRB-

-LRB-

mapRT

f

xs

-RRB-

We

can

implement

the

constructors

by

the

unary

constructor

function

Bud

and

the

binary

constructor

function

Rose

We

use

the

implementation

of

the

relator

List

as

we

discussed

before

Elements

of

the

class

of

types

corresponding

to

this

implementation

of

the

relator

RoseTree

may

be

graphically

represented

by

Rose

App

Bud

App

Rose

App

Bud

Nill

App

Bud

Nill

We

can

clearly

identify

the

different

parts

of

the

RoseTree

structure

The

above

implementation

of

the

map

function

however

is

not

correct

Why

Consider

the

types

of

the

different

parts

of

the

implementation

in

the

second

defining

equation

of

mapRT

Relators

Datatypes

and

Polymorphism

Implementing

Relators

mapRT

-LRB-

a

b

-RRB-

-LRB-

RoseTree

a

RoseTree

b

-RRB-

x

a

xs

List

-LRB-

RoseTree

a

-RRB-

Bud

x

RoseTree

a

Rose

x

xs

RoseTree

a

If

we

now

consider

the

second

defining

equation

for

the

mapRT

function

we

can

observe

that

the

function

mapRT

is

applied

to

an

element

of

type

List

-LRB-

RoseTree

a

-RRB-

which

is

in

conflict

with

the

typing

of

the

mapRT

function

itself

We

need

an

instance

of

the

mapList

function

on

the

type

List

a

A

correct

implementation

of

the

map

function

corresponding

to

the

relator

RoseTree

is

given

by

mapRT

-LRB-

a

b

-RRB-

-LRB-

RoseTree

a

RoseTree

b

-RRB-

mapRT

f

-LRB-

Bud

x

-RRB-

Bud

-LRB-

f

x

-RRB-

mapRT

f

-LRB-

Rose

x

xs

-RRB-

Rose

-LRB-

f

x

-RRB-

-LRB-

-LRB-

mapList.mapRT

-RRB-

f

xs

-RRB-

This

implementation

-LCB-

evidently

-LCB-

needs

a

mapList.mapRT

function

instead

of

a

single

mapRT

if

we

consider

the

above

graphical

representation

and

the

data-definition

of

the

relators

List

and

RoseTree

this

is

quite

obvious

since

we

do

not

want

to

apply

a

function

to

the

lists

but

we

want

to

map

a

function

over

the

lists

The

important

moral

is

when

considering

the

implementation

of

composite

relators

one

always

has

to

consider

typing

issues

with

special

interest

and

special

care

If

we

want

to

implement

the

above

mapRT

function

as

an

instance

of

the

constructor

class

Functor

we

have

to

use

a

superclass

construction

to

make

clear

that

there

are

in

fact

several

different

instantiations

of

the

function

map

present

in

this

instance

Consequently

we

can

implement

the

function

mapRT

as

an

instance

of

the

class

Functor

by

instance

Functor

List

Functor

RoseTree

where

map

f

-LRB-

Bud

x

-RRB-

Bud

-LRB-

f

x

-RRB-

map

f

-LRB-

Rose

x

xs

-RRB-

Rose

-LRB-

f

x

-RRB-

-LRB-

-LRB-

map

map

-RRB-

f

xs

-RRB-

Implementing

relators

in

general

In

the

preceeding

subsections

we

discussed

the

implementation

of

unary

map

relators

and

the

implementation

of

composite

unary

map

relators

In

this

subsection

we

consider

the

implementation

of

relators

in

general

In

particular

we

consider

the

implementations

of

the

basic

relators

and

Relators

in

general

As

an

example

we

will

consider

the

relator

F

which

is

defined

by

F

X

I?X

If

we

would

use

the

same

methodology

as

with

previous

examples

we

would

consider

F

I

to

implement

the

function

from

types

to

types

and

the

map

function

coming

with

the

relator

This

would

then

result

in

the

following

implementation

Relators

Datatypes

and

Polymorphism

Implementing

Relators

data

F

a

UnitF

TimesF

a

a

instance

Functor

F

where

map

f

-LRB-

UnitF

-RRB-

UnitF

map

f

-LRB-

TimesF

x

y

-RRB-

TimesF

-LRB-

x

-RRB-

-LRB-

f

y

-RRB-

Note

that

we

did

not

apply

f

to

x

i.e.

we

applied

a

hidden

identity

function

to

x

But

this

implementation

is

hardly

what

we

want

since

the

implementation

of

the

function

from

types

to

types

treats

the

spec

I

the

same

way

as

the

spec

X

Since

I

is

a

constant

spec

and

X

is

not

we

want

the

implementation

to

take

this

asymmetry

into

consideration

How

can

we

do

this

Consider

the

binary

relator

which

is

defined

by

X

B?X

Using

this

definition

we

find

that

F

We

will

now

try

to

implement

the

unary

relator

This

relator

may

be

implemented

by

data

F

a

b

UnitF

TimesF

a

b

instance

Functor

-LRB-

F

a

-RRB-

where

map

f

-LRB-

UnitF

-RRB-

UnitF

map

f

-LRB-

TimesF

x

y

-RRB-

TimesF

-LRB-

x

-RRB-

-LRB-

f

y

-RRB-

The

fact

that

we

have

implemented

and

not

is

exemplified

by

the

implementation

of

the

map

function

where

we

-LCB-

again

-LCB-

did

not

apply

f

to

x.

Note

the

fact

that

we

instantiated

the

Functor

class

with

F

a

and

not

with

F

This

implementation

does

indeed

respect

the

asymmetry

between

the

spec

I

and

the

spec

X

But

what

about

the

implementation

of

the

binary

relator

in

general

i.e.

for

non

fixed

spec

B

Since

is

a

binary

relator

its

function

from

types

to

types

will

again

be

implemented

by

a

binary

type

constructor

In

contrast

to

previous

examples

however

is

a

truly

binary

relator

One

of

the

consequences

is

that

we

can

not

implement

the

map

function

of

as

an

instance

of

the

class

Functor

Relator

can

be

implemented

by

data

F

a

b

UnitF

TimesF

a

b

mapF

-LRB-

a

c

-RRB-

-LRB-

b

d

-RRB-

-LRB-

F

a

b

F

c

d

-RRB-

mapF

f

g

-LRB-

UnitF

-RRB-

UnitF

mapF

f

g

-LRB-

TimesF

x

y

-RRB-

TimesF

-LRB-

f

x

-RRB-

-LRB-

g

y

-RRB-

If

we

compare

the

type

of

mapF

to

the

general

type

of

the

function

map

in

the

definition

of

the

class

Functor

we

see

that

these

types

are

very

different

The

reason

for

this

is

that

the

class

Functor

groups

the

map

functions

via

a

constructor

class

defined

for

unary

type

constructors

whereas

F

is

a

binary

type

constructor

If

we

want

to

group

the

map

functions

for

binary

type

constructors

we

have

to

define

a

new

constructor

class

class

f

where

-LRB-

a

c

-RRB-

-LRB-

b

d

-RRB-

-LRB-

f

a

b

f

c

d

-RRB-

Relators

Datatypes

and

Polymorphism

Implementing

Relators

We

then

can

implement

the

map

function

mapF

by

instance

F

where

f

g

-LRB-

UnitF

-RRB-

UnitF

f

g

-LRB-

TimesF

x

y

-RRB-

TimesF

-LRB-

f

x

-RRB-

-LRB-

g

y

-RRB-

Note

that

we

have

two

functions

in

our

function

because

the

two

type

variables

of

the

type

constructor

may

be

instantiated

by

different

types

This

implementation

suggests

that

we

have

to

construct

such

a

constructor

class

for

every

arity

that

is

one

constructor

class

for

unary

type

constructors

one

constructor

class

for

binary

type

constructors

one

constructor

class

for

ternary

type

constructors

and

so

on

This

implies

that

we

have

to

construct

such

a

different

constructor

class

for

unary

relators

for

binary

relators

for

ternary

relators

and

so

on

This

means

that

we

can

not

implement

one

single

polymorphic

map

function

for

all

possible

relators

This

suggests

that

we

can

not

implement

functions

over

all

possible

relators

i.e.

we

can

not

implement

functions

that

are

parameterised

by

a

relator

without

instantiating

the

relator

The

basic

relators

How

can

we

implement

the

relators

and

Let

us

consider

the

implementation

of

the

The

spec-calculus

shows

us

that

R?S

-LRB-

Rffio

-RRB-

-LRB-

S

ffiAE

-RRB-

So

we

may

implement

the

relator

by

data

Product

a

b

Times

a

b

split

a

b

Product

a

b

split

x

y

Times

x

y

lpr

Product

a

b

a

lpr

-LRB-

Times

x

y

-RRB-

x

rpr

Product

a

b

b

rpr

-LRB-

Times

x

y

-RRB-

y

instance

Product

where

f

g

z

-LRB-

-LRB-

f.lpr

-RRB-

z

-RRB-

split

-LRB-

-LRB-

g.rpr

-RRB-

z

-RRB-

In

this

implementation

we

used

the

functions

split

lpr

and

rpr

These

functions

-LCB-

the

implementations

of

the

spec-operators

o

and

AE

-LCB-

are

also

well-known

in

functional

programming

You

do

not

recognise

them

Let

us

then

simulate

the

datatype

Product

a

b

by

the

built-in

datatype

of

pairs

-LRB-

-LRB-

a

b

-RRB-

-RRB-

We

then

may

implement

split

simply

by

split

a

b

-LRB-

a

b

-RRB-

split

x

y

-LRB-

x

y

-RRB-

Relators

Datatypes

and

Polymorphism

Implementing

Relators

The

functions

lpr

and

rpr

may

be

implemented

by

the

built-in

functions

fst

and

snd

Since

o

and

AE

are

polymorphic

we

would

like

the

implementations

of

these

operators

to

be

ad-hoc

polymorphic

But

that

is

in

general

not

possible

To

implement

a

polymorphic

function

with

a

type

class

or

a

constructor

class

we

need

a

general

type

for

this

function

that

holds

-LCB-

can

be

inferred

-LCB-

for

all

types

for

which

we

intend

to

instantiate

the

class

If

we

could

construct

such

a

polymorphic

version

of

the

lpr

rpr

and

split

functions

we

would

like

to

instantiate

them

for

data

Product

a

b

Times

a

b

data

List

a

Nill

App

-LRB-

a

-RRB-

-LRB-

List

a

-RRB-

data

SnocList

a

Nils

Snoc

-LRB-

SnocList

a

-RRB-

-LRB-

a

-RRB-

I

can

not

find

a

general

type

for

the

polymorphic

versions

of

the

functions

lpr

rpr

and

split

such

that

I

can

instantiate

them

over

all

three

classes

of

datatypes

without

explicitly

defining

a

universe

containing

all

three

classes

Can

you

The

only

possibility

for

implementing

a

somewhat

polymorphic

version

of

these

functions

is

by

explicitly

exploiting

the

fact

that

we

can

simulate

all

binary

constructor

functions

by

a

pair

We

define

a

type

class

Coercions

such

that

class

Coercions

a

b

where

coerce

a

b

instance

Coercions

-LRB-

Product

a

b

-RRB-

-LRB-

a

b

-RRB-

where

coerce

-LRB-

Times

x

y

-RRB-

-LRB-

x

y

-RRB-

instance

Coercions

-LRB-

List

a

-RRB-

-LRB-

a

List

a

-RRB-

where

coerce

-LRB-

App

v

lv

-RRB-

-LRB-

v

lv

-RRB-

instance

Coercions

-LRB-

SnocList

a

-RRB-

-LRB-

SnocList

a

a

-RRB-

where

coerce

-LRB-

Snoc

xs

x

-RRB-

-LRB-

xs

x

-RRB-

We

can

now

redefine

our

functions

lpr

rpr

and

split

by

lpr

-LRB-

a

b

-RRB-

a

lpr

-LRB-

x

y

-RRB-

x

rpr

-LRB-

a

b

-RRB-

b

rpr

-LRB-

x

y

-RRB-

y

split

a

b

-LRB-

a

b

-RRB-

split

x

y

-LRB-

x

y

-RRB-

We

now

can

use

these

polymorphic

implementations

of

the

projection

functions

on

the

types

for

which

we

implemented

an

instance

of

the

type

class

Coercions

For

instance

rpr

-LRB-

coerce

-LRB-

Snoc

-LRB-

Snoc

Nils

-RRB-

-RRB-

-LRB-

SnocList

Int

Int

-RRB-

-RRB-

lpr

-LRB-

coerce

-LRB-

Times

-RRB-

-LRB-

Int

Int

-RRB-

-RRB-

Relators

Datatypes

and

Polymorphism

Equality

vs.

Isomorphism

result

in

and

respectively

Since

we

had

to

define

the

type

class

Coercions

using

a

parameter

type

class

we

have

to

supply

our

expressions

with

explicit

typing

representing

the

type

of

the

result

of

the

application

of

the

function

coerce

Because

of

the

fact

that

we

have

to

implement

the

binary

operator

by

means

of

different

binary

constructor

functions

we

have

problems

implementing

the

truly

polymorphic

functions

o

AE

and

With

respect

to

the

implementations

of

functions

like

o

AE

and

we

can

observe

that

we

can

not

identify

a

general

pattern

for

the

types

of

these

functions

such

that

we

could

implement

them

directly

by

a

type

or

constructor

class

What

about

the

relator

Can

we

implement

the

relator

Yes

we

can

We

may

implement

the

relator

by

data

Sum

a

b

Inl

a

Inr

b

mapS

-LRB-

a

c

-RRB-

-LRB-

b

d

-RRB-

Sum

a

b

Sum

c

d

mapS

f

g

z

case

z

of

Inl

x

Inl

-LRB-

f

x

-RRB-

Inr

y

Inr

-LRB-

g

y

-RRB-

Since

we

can

use

the

more

than

once

in

an

expression

we

can

implement

the

binary

relator

by

a

binary

type

constructor

where

each

argument

may

be

of

a

different

type

From

the

above

we

may

conclude

that

implementing

relators

in

general

is

not

very

difficult

But

defining

-LRB-

ad-hoc

-RRB-

polymorphic

functions

over

different

kinds

of

data

structures

can

be

quite

difficult

and

is

seldom

straightforward

This

implies

that

implementing

programs

or

functions

that

are

parameterised

by

relators

is

in

general

difficult

if

not

impossible

in

functional

programming

Since

and

are

binary

relators

we

could

implement

all

other

relators

as

composite

relators

since

they

are

all

defined

in

terms

of

and

Using

the

above

implementations

of

the

relators

and

we

could

consider

all

relators

to

be

composite

relators

and

implement

them

in

terms

of

the

implementations

of

and

But

we

will

not

do

this

in

this

report

Why

not

We

will

return

to

this

subject

in

Chapter

Although

many

programming

languages

contain

-LRB-

some

of

the

above

-RRB-

features

it

is

the

underlying

mathematical

tractability

of

functional

languages

which

is

responsible

for

much

of

the

interest

in

functional

programming

The

phrase

referential

transparency

is

used

to

describe

a

key

mathematical

property

of

functional

programming

the

ability

to

universally

substitute

equals

for

equals

The

importance

of

referential

transparency

is

that

simple

but

powerful

equational

reasoning

-LRB-

akin

to

everyday

mathematics

-RRB-

may

be

used

to

reason

formally

about

programs

D.

Sands

-LSB-

-RSB-

Equality

vs.

Isomorphism

Being

based

on

the

calculus

of

relations

and

thus

on

a

complete

lattice

structure

fixed

points

in

the

spec-calculus

are

true

fixed

points

-LRB-

cf.

-LSB-

-RSB-

-RRB-

and

not

fixed

points

up

to

isomorphism

Relators

Datatypes

and

Polymorphism

Equality

vs.

Isomorphism

-LRB-

cf.

-LSB-

-RSB-

-RRB-

For

example

the

relator

List

is

defined

by

List

R

-LSB-

R?X

-RSB-

and

we

have

List

R

R?List

R

and

not

just

List

R

R?List

R

Programming

languages

often

hide

the

distinction

so

that

it

is

not

immediately

obvious

to

the

programmer

whether

or

not

fixed

points

are

defined

up

to

isomorphism

The

distinction

becomes

clear

when

one

tries

to

exploit

algebraic

properties

of

the

fixed

point

operator

One

such

property

of

vital

importance

is

the

fusion

law

f

-LRB-

g

fflf

-RRB-

-LRB-

f

fflg

-RRB-

for

all

monotonic

endofunctions

f

and

g

This

law

can

be

applied

directly

in

spec

calculus

to

map

relators

as

follows

Theorem

Suppose

is

a

binary

relator

and

F

is

a

unary

relator

Define

the

relators

y

and

z

by

y

R

-LSB-

R

F

X

-RSB-

z

R

-LSB-

F

-LRB-

R

X

-RRB-

-RSB-

Then

Fffly

z

Proof

Instantiate

the

fusion

law

with

f

F

and

g

R

As

an

example

of

this

theorem

consider

the

relators

Tree

and

PairTree

defined

by

Tree

R

-LSB-

R

X?X

-RSB-

PairTree

R

-LSB-

-LRB-

R+X

-RRB-

-LRB-

R+X

-RRB-

-RSB-

Then

we

have

PairTree

-LSB-

Tree

R

Tree

R

-RSB-

-LRB-

-RRB-

Having

true

fixed

points

is

enormously

advantageous

to

economical

calculation

because

one

has

fewer

type

coercions

-LRB-

cf.

-LSB-

-RSB-

-RRB-

to

think

about

To

illustrate

this

let

us

compare

-LRB-

-RRB-

with

its

equivalent

formulation

in

a

conventional

programming

language

In

a

language

like

Gofer

the

relators

Tree

and

PairTree

might

be

implemented

as

follows

Relators

Datatypes

and

Polymorphism

Summary

data

Tree

a

Leaf

a

Branch

-LRB-

Tree

a

-RRB-

-LRB-

Tree

a

-RRB-

data

Sub

a

Inl

a

Inr

-LRB-

PairTree

a

-RRB-

data

PairTree

a

Pair

-LRB-

Sub

a

-RRB-

-LRB-

Sub

a

-RRB-

A

pair

of

Trees

is

however

not

identical

to

a

PairTree

but

they

are

isomorphic

Specifically

in

Gofer

one

has

to

write

functions

-LRB-

coercions

-RRB-

mapping

pairs

of

Trees

to

PairTrees

as

follows

pttotp

-LRB-

x

y

-RRB-

Pair

-LRB-

f

x

-RRB-

-LRB-

f

y

-RRB-

where

f

-LRB-

Leaf

v

-RRB-

Inr

v

f

-LRB-

Branch

v

w

-RRB-

Inr

-LRB-

pttotp

-LRB-

v

w

-RRB-

-RRB-

tptopt

-LRB-

Pair

x

y

-RRB-

-LRB-

g

x

g

y

-RRB-

where

g

-LRB-

Inl

v

-RRB-

Leaf

v

g

-LRB-

Inr

v

-RRB-

-LRB-

uncurry

Branch

-RRB-

-LRB-

tptopt

v

-RRB-

This

lack

of

economy

in

programming

languages

may

or

may

not

be

regarded

as

undesirable

We

regard

them

as

undesirable

So

although

Gofer

is

a

referential

transparent

language

types

can

not

be

substituted

by

other

types

on

basis

of

equals

for

equals

Summary

In

this

chapter

we

discussed

the

implementation

of

relators

We

have

seen

that

we

can

very

systematically

construct

implementations

of

relators

We

observed

that

the

implementation

of

a

relator

corresponds

to

a

combination

of

ffl

a

-LRB-

recursive

-RRB-

datatype

which

is

implemented

by

a

data-definition

and

which

-LRB-

implicitly

-RRB-

defines

-LCB-

a

type

constructor

and

-LCB-

constructor

functions

ffl

a

map

function

which

is

-LRB-

recursively

-RRB-

defined

over

the

datatype

We

have

also

seen

that

when

implementing

composite

relators

we

should

always

take

into

consideration

the

different

types

of

the

different

instances

of

the

functions

in

the

implementation

of

the

map

function

We

also

observed

that

constructing

polymorphic

implementations

of

programs

or

functions

that

are

parameterised

over

relators

is

in

general

quite

difficult

Specifically

the

most

notorious

problems

are

ffl

When

we

want

to

construct

a

polymorphic

implementation

of

a

class

of

functions

by

means

of

a

type

class

or

a

constructor

class

we

have

to

have

a

non-ambiguous

general

type

for

all

member

functions

of

that

class

We

can

only

define

an

instance

of

this

class

over

a

specific

datatype

if

this

datatype

does

not

conflict

with

this

general

type

Relators

Datatypes

and

Polymorphism

Exercises

Another

restriction

is

that

a

constructor

class

can

only

group

type

constructors

that

have

the

same

arity

This

of

course

severely

limits

the

possibilities

for

constructing

truly

polymorphic

implementations

of

functions

that

are

parameterised

over

various

general

relators

ffl

Since

datatypes

in

functional

programming

can

not

be

equal

but

only

isomorphic

we

are

restricted

with

respect

to

implementing

relators

This

implies

that

even

if

the

relators

are

identical

we

need

explicit

coercion

functions

between

the

datatypes

corresponding

to

these

relators

For

instance

consider

the

relator

List

and

two

possible

implementations

of

the

function

from

types

to

types

of

this

relator

data

List

a

Nill

App

-LRB-

a

-RRB-

-LRB-

List

a

-RRB-

data

ConsList

a

Nilc

Cons

-LRB-

a

-RRB-

-LRB-

ConsList

a

-RRB-

Since

both

these

implementations

represent

the

same

relator

the

structure

described

by

both

is

identical

The

representations

of

these

two

implementations

are

however

different

List

versus

ConsList

Nill

versus

Nilc

and

App

versus

Cons

This

means

that

we

need

explicit

coercion

functions

relating

the

representations

to

each

other

ffl

Another

major

annoyance

is

the

fact

that

we

have

to

implement

all

instances

of

constant

specs

by

different

but

isomorphic

constructor

functions

A

final

remark

that

has

to

be

made

is

that

our

implementations

are

not

really

parameterised

by

datatypes

The

type

classes

and

constructor

classes

we

use

only

indicate

how

the

function

has

to

behave

when

applied

to

elements

of

a

specific

datatype

This

means

that

we

still

have

to

implement

an

instance

of

the

type

class

or

constructor

class

for

each

type

or

type

constructor

and

thus

that

we

still

have

to

implement

a

function

for

each

type

or

type

constructor

We

therefore

can

only

simulate

the

parameterisation

by

datatypes

Exercises

x

Exercise

Implement

Bool

which

is

defined

by

Bool

x

Exercise

Implement

Nat

which

is

defined

by

Nat

-LSB-

X

-RSB-

Relators

Datatypes

and

Polymorphism

Exercises

x

Exercise

-LRB-

-RRB-

Implement

the

relator

Tree

which

is

defined

by

Tree

R

-LSB-

R

X?X

-RSB-

Relators

Datatypes

and

Polymorphism

Chapter

Calculating

Functions

In

this

chapter

we

discuss

a

class

of

functions

which

is

very

important

in

the

spec-calculus

the

catamorphisms

These

catamorphisms

roughly

correspond

to

functions

which

are

defined

by

structural

recursion

Catamorphisms

In

the

previous

chapter

we

learned

how

to

implement

relators

One

part

of

this

implementation

is

a

map

function

that

maps

functions

to

functions

However

until

now

we

do

not

have

any

functions

that

we

can

map

In

general

in

a

real

program

more

than

one

datatype

is

used

and

several

functions

are

defined

on

a

single

datatype

Functions

in

functional

programs

are

defined

by

means

of

simple

structural

recursion

over

a

datatype

e.g.

the

map

functions

in

the

previous

chapter

Recursive

functions

are

central

to

the

style

of

applicative

programming

and

we

hope

that

the

reader

feels

that

this

is

an

easy

and

natural

way

to

program

-LRB-

cf.

-LSB-

-RSB-

-RRB-

This

method

resolves

itself

into

a

way

of

defining

functions

by

cases

and

is

one

heavily

used

in

mathematics

and

logic

Cases

are

of

two

kinds

ffl

Recursive

cases

where

we

use

some

recurrence

relation

to

calculate

the

values

in

terms

of

applications

of

the

function

to

other

simpler

values

ffl

Base

cases

-LRB-

often

only

one

-RRB-

which

define

the

function

using

a

more

direct

definition

In

the

spec-calculus

a

counterpart

to

this

kind

of

functions

are

the

catamorphisms

These

catamorphisms

are

one

of

the

building

blocks

of

the

spec-calculus

In

fact

catamorphisms

simply

encapsulate

a

particular

recursion

pattern

in

a

very

concise

and

elegant

notation

However

not

all

recursion

patterns

can

be

encapsulated

in

a

catamorphism

e.g.

the

recursion

pattern

corresponding

to

the

well

known

factorial

function

can

not

be

captured

by

a

catamorphism

For

situations

where

a

catamorphism

does

not

suffice

there

are

other

possibilities

e.g.

paramorphisms

-LRB-

cf.

-LSB-

-RSB-

-RRB-

These

however

are

beyond

the

scope

of

this

report

In

the

remainder

of

this

report

we

only

consider

catamorphisms

Catamorphisms

Definition

-LRB-

-LRB-

-RRB-

-RRB-

Let

F

be

an

arbitrary

relator

and

let

R

be

an

arbitrary

spec

Define

the

function

-LRB-

F

R

-RRB-

by

-LRB-

F

R

-RRB-

-LSB-

R

ffi

F

X

-RSB-

In

words

-LRB-

F

R

-RRB-

is

the

least

solution

of

the

equation

X

X

R

ffi

F

X

We

call

specs

R

of

the

form

-LRB-

F

R

-RRB-

F-catamorphisms

Corollary

-LRB-

F

R

-RRB-

R

ffi

-LRB-

F

R

-RRB-

F

-LRB-

F

I

-RRB-

-LRB-

F

R

-RRB-

-LSB-

R

ffi

F

X

-RSB-

If

it

is

clear

which

relator

is

being

used

then

we

will

omit

the

name

of

the

relator

and

simply

write

-LRB-

R

-RRB-

instead

of

-LRB-

F

R

-RRB-

In

general

catamorphisms

are

relational

but

throughout

this

report

we

only

consider

functional

catamorphisms

Since

they

are

functional

we

should

be

able

to

implement

them

directly

in

a

functional

programming

language

In

functional

programming

coproducts

roughly

correspond

to

the

case

statements

Axel

Poign?e

-LSB-

-RSB-

Theorem

-LRB-

Computation

rules

for

-LRB-

-RRB-

-RRB-

For

an

arbitrary

sum

relator

F

and

relators

G

and

H

such

that

F

G

H

and

arbitrary

specs

R

and

S

we

have

-LRB-

F

-RRB-

ffi

o

F

R

ffi

G

-LRB-

F

-RRB-

-LRB-

F

-RRB-

ffi

F

S

ffi

H

-LRB-

F

-RRB-

The

computation

rules

for

-LRB-

-RRB-

correspond

to

saying

that

an

F-catamorphism

may

be

implemented

by

means

of

simple

structural

recursion

over

the

data

structure

which

may

be

associated

with

relator

F

i.e.

over

F.

Can

we

see

this

Recall

that

the

spec-constructors

o

F

and

F

correspond

to

the

constructor

functions

that

come

with

the

type

constructor

representing

the

function

from

types

to

types

of

relator

F

In

functional

programming

these

Calculating

Functions

Implementing

Catamorphisms

constructor

functions

are

used

for

the

recursive

definitions

of

functions

over

the

types

corresponding

to

the

type

constructor

In

fact

an

F-catamorphism

breaks

down

an

F-structure

and

recursively

applies

the

F-catamorphism

In

the

previous

chapter

we

already

came

across

some

catamorphisms

the

map

functions

in

the

previous

chapter

Recall

that

Nat

-LSB-

X

-RSB-

List

R

-LSB-

R?X

-RSB-

Tree

R

-LSB-

R

X?X

-RSB-

The

common

pattern

in

these

equations

was

that

we

seek

the

least

solution

of

an

equation

X

X

R

X

where

is

a

binary

relator

We

know

that

this

equation

does

indeed

have

a

least

solution

for

all

R

the

solution

is

-LRB-

R

-RRB-

More

important

the

study

of

catamorphisms

in

-LSB-

-RSB-

gives

us

a

unicity

property

for

the

least

solution

of

the

above

equation

Specifically

we

have

X

-LSB-

R

X

-RSB-

f

is

a

binary

relator

g

X

-LSB-

R

I

ffi

I

X

-RSB-

f

Definition

-LRB-

-RRB-

g

X

-LRB-

I

R

I

-RRB-

Let

us

introduce

a

shorthand

for

the

relator

-LRB-

R

-LRB-

I

R

I

-RRB-

-RRB-

we

denote

it

by

R.

is

a

map

relator

Thus

R

-LRB-

I

R

I

-RRB-

Examples

are

Nat

-LRB-

-LRB-

X

X

-RRB-

I

-RRB-

List

R

-LRB-

-LRB-

X

I?X

-RRB-

R?I

-RRB-

Tree

R

-LRB-

-LRB-

X

X?X

-RRB-

R

I?I

-RRB-

So

with

each

map

relator

V

such

that

V

R

-LRB-

I

R

I

-RRB-

we

may

associate

a

relator

I

If

we

reconsider

our

definition

of

an

initial

relator

we

find

that

V

I

Implementing

Catamorphisms

Implementing

map

functions

If

we

consider

the

above

definitions

of

the

map

relators

we

can

actually

observe

that

in

the

spec-calculus

the

relator

is

a

function

from

types

to

types

and

a

map

function

Using

the

above

definitions

of

the

map

relators

we

can

actually

construct

an

Calculating

Functions

Implementing

Catamorphisms

implementation

of

the

map

functions

corresponding

to

these

relators

For

instance

consider

the

definition

of

List

R

and

let

us

introduce

m

R

which

is

defined

by

m

R

-LRB-

List

R?I

-RRB-

We

use

this

definition

to

make

a

clear

distinction

between

the

function

from

types

to

types

and

the

function

that

maps

functions

to

functions

corresponding

to

relator

List

but

actually

m

R

List

R

for

all

R.

For

relator

List

we

have

o

List

ffi

List

ffi

-LRB-

I?List

I

-RRB-

Using

the

computation

rules

for

-LRB-

-RRB-

we

get

for

m

R

m

R

ffi

o

List

o

List

m

R

ffi

List

-LRB-

ffi

-LRB-

R?I

-RRB-

-RRB-

ffi

-LRB-

I?m

R

-RRB-

For

m

R

ffi

List

we

have

m

R

ffi

List

f

Computation

rules

for

-LRB-

-RRB-

g

-LRB-

ffi

-LRB-

R?I

-RRB-

-RRB-

ffi

-LRB-

I?m

R

-RRB-

f

Associativity

ffi

g

ffi

-LRB-

-LRB-

R?I

-RRB-

ffi

-LRB-

I?m

R

-RRB-

-RRB-

f

fusion

g

ffi

-LRB-

R

m

R

-RRB-

f

-LRB-

-RRB-

g

ffi

-LRB-

-LRB-

I?List

I

-RRB-

ffi

-LRB-

R?m

R

-RRB-

-RRB-

f

Definition

List

g

List

ffi

-LRB-

R?m

R

-RRB-

At

-LRB-

-RRB-

we

use

explicitly

that

m

List

and

thus

that

m

is

a

relator

Since

m

is

a

relator

we

also

have

that

m

R

f

I

is

unit

element

of

ffi

g

m

-LRB-

I

ffiR

-RRB-

Calculating

Functions

Implementing

Catamorphisms

f

m

is

a

relator

g

m

I

ffi

m

R

f

m

List

g

List

I

ffi

m

R

Consequently

R

m

R

f

above

g

R

-LRB-

List

I

ffi

m

R

-RRB-

f

I

is

unit

element

of

ffi

g

-LRB-

I

ffiR

-RRB-

-LRB-

List

I

ffi

m

R

-RRB-

f

fusion

g

-LRB-

I?List

I

-RRB-

ffi

-LRB-

R?m

R

-RRB-

So

we

get

for

m

R

m

R

ffi

o

List

o

List

m

R

ffi

List

List

ffi

-LRB-

R?m

R

-RRB-

From

these

computation

rules

we

can

very

easily

construct

the

following

implementation

of

m

m

-LRB-

a

b

-RRB-

-LRB-

List

a

List

b

-RRB-

m

f

-LRB-

Nill

-RRB-

Nill

m

f

-LRB-

App

v

lv

-RRB-

App

-LRB-

f

v

-RRB-

-LRB-

m

f

lv

-RRB-

If

we

compare

this

implementation

to

the

implementation

for

the

mapList

in

Chapter

we

see

that

they

are

identical

-LRB-

modulo

identifiers

-RRB-

Another

example

Let

us

look

at

another

example

of

a

catamorphism

and

consider

the

length

function

on

lists

This

function

is

defined

by

Nat

-LSB-

X

-RSB-

zero

o

Nat

succ

Nat

List

R

-LSB-

R?X

-RSB-

l

Nat

List

R

l

-LRB-

List

zero

-LRB-

succffiAE

-RRB-

-RRB-

In

this

definition

there

are

two

relators

Nat

and

List

We

need

the

implementation

of

both

relators

In

the

previous

chapter

we

implemented

the

relator

List

An

implementation

of

this

relator

is

given

by

Calculating

Functions

Implementing

Catamorphisms

data

List

a

Nill

App

-LRB-

a

-RRB-

-LRB-

List

a

-RRB-

instance

Functor

List

where

map

f

-LRB-

Nill

-RRB-

Nill

map

f

-LRB-

App

v

lv

-RRB-

App

-LRB-

f

v

-RRB-

-LRB-

map

f

lv

-RRB-

o

List

can

be

implemented

by

Nill

List

can

be

implemented

by

App

The

relator

Nat

is

a

relator

From

its

definition

we

may

conclude

that

Nat

-LSB-

X

-RSB-

This

implies

that

the

constructors

of

relator

Nat

are

given

by

o

Nat

ffi

Nat

ffi

Nat

The

relator

Nat

can

now

be

implemented

by

data

Nat

Zero

Succ

Nat

o

Nat

can

be

implemented

by

Zero

Nat

can

be

implemented

by

Succ

We

did

not

implement

a

map

function

for

this

relator

since

this

is

simply

the

identity

function

on

Nat

Now

that

we

have

implementations

for

the

relators

List

and

Nat

we

may

proceed

with

the

implementation

of

the

function

l

Since

l

is

defined

as

a

functional

catamorphism

we

can

apply

the

computation

rules

for

-LRB-

-RRB-

on

-LRB-

List

zero

-LRB-

succffiAE

-RRB-

-RRB-

This

results

in

l

ffi

o

List

zero

ffi

G

l

l

ffi

List

succ

ffi

AE

ffi

H

l

where

G

X

H

X

I?X

If

we

now

substitute

the

definitions

of

zero

succ

G

and

H

we

get

l

ffi

o

List

o

Nat

ffi

l

ffi

List

Nat

ffi

AE

ffi

-LRB-

I?l

-RRB-

Substituting

the

definitions

of

the

constructors

of

relator

Nat

and

using

that

and

that

AEffi

-LRB-

I

R

-RRB-

RffiAE

for

all

R

we

get

l

ffi

o

List

ffi

l

ffi

List

ffi

Nat

ffi

-LRB-

lffiAE

-RRB-

If

we

now

reconsider

once

again

the

implementations

of

the

relators

List

and

Nat

we

find

that

we

can

implement

the

function

l

by

Calculating

Functions

Monad

Decomposition

Exemplified

length

List

a

Nat

length

-LRB-

Nill

-RRB-

Zero

length

-LRB-

App

v

lv

-RRB-

Succ

-LRB-

length

lv

-RRB-

Note

that

we

silently

unfolded

the

implementation

of

AE

Gofer

just

like

Haskell

provides

a

case

expression

which

can

be

used

to

make

the

pattern

matching

we

have

encountered

in

function

definitions

more

explicit

and

which

provides

a

kind

of

conditional

based

on

the

success

or

failure

of

pattern

matching

Using

a

case

expression

the

function

l

may

be

implemented

by

length

List

a

Nat

length

l

case

l

of

Nill

Zero

App

v

lv

Succ

-LRB-

length

lv

-RRB-

Here

we

see

that

an

explicit

list

of

two

patterns

Nill

and

App

v

lv

are

matched

against

l

If

we

apply

the

above

function

length

to

the

list

App

-LRB-

App

-LRB-

App

Nill

-RRB-

-RRB-

we

get

as

a

result

Succ

-LRB-

Succ

-LRB-

Succ

Zero

-RRB-

-RRB-

which

is

equivalent

to

just

as

we

expected

By

now

the

reader

should

have

a

fairly

good

-LRB-

intuitive

-RRB-

idea

of

what

catamorphisms

are

and

how

he

can

calculate

with

them

In

the

next

section

we

investigate

the

implementation

of

catamorphisms

somewhat

more

by

means

of

an

example

Say

I

write

an

evaluator

in

a

pure

functional

language

To

add

an

execution

trace

to

it

I

need

to

modify

each

recursive

call

to

pass

around

such

traces

appropriately

Or

could

I

use

a

monad

Philip

Wadler

-LSB-

-RSB-

Monad

Decomposition

Exemplified

In

-LSB-

-RSB-

R.C.

Backhouse

constructs

a

monad

decomposition

theorem

and

two

distinct

proofs

The

motive

for

the

second

proof

is

to

construct

a

proof

such

that

the

result

would

be

two

witnesses

to

the

isomorphism

that

is

predicted

by

the

monad

decomposition

theorem

The

witnesses

constructed

in

the

process

of

proving

the

theorem

are

all

catamorphisms

In

this

section

we

are

going

to

investigate

the

implementation

of

these

catamorphisms

To

be

able

to

calculate

with

these

catamorphisms

we

first

have

to

consider

the

following

definitions

and

theorems

Definition

-LRB-

F

-RRB-

Let

F

be

an

arbitrary

relator

and

let

X

and

Y

be

arbitrary

specs

Define

the

binary

relator

F

by

X?FY

X

F

Y

Calculating

Functions

Monad

Decomposition

Exemplified

Furthermore

denote

-LRB-

I?F

R

-RRB-

by

-LRB-

R

-RRB-

F.

From

the

definition

of

-LRB-

R

-RRB-

K

we

may

conclude

that

this

is

in

fact

a

-LRB-

X

I

K

X

-RRB-

catamorphism

Theorem

For

arbitrary

relator

K

and

arbitrary

specs

R

and

S

-LRB-

-RRB-

K

R

-LRB-

S

ffi

K

-LRB-

-RRB-

K

-RRB-

If

we

take

a

closer

look

at

this

theorem

then

we

see

that

this

theorem

corresponds

to

a

one

time

unfolding

of

the

recursive

definition

of

-LRB-

-RRB-

K.

Definition

-LRB-

FA

-RRB-

Let

F

be

an

arbitrary

relator

and

let

X

be

an

arbitrary

spec

Define

the

unary

relator

FA

by

FA

X

-LRB-

X?F

-RRB-

For

KA

we

have

KA

R

-LRB-

R?K

-RRB-

f

Definition

R?K

g

KA

R

-LSB-

R

K

X

-RSB-

So

KA

-LSB-

I

K

X

-RSB-

This

implies

that

-LRB-

R

-RRB-

K

is

a

KA-catamorphism

Consequently

we

can

implement

-LRB-

R

-RRB-

K

by

means

of

structural

recursion

over

KA

Theorem

-LRB-

Constructors

of

FA

-RRB-

Let

F

be

an

arbitrary

sum

relator

The

constructors

of

FAare

given

by

o

FA

FA

I

ffi

FA

FA

I

ffi

Proof

Since

FA

-LSB-

R?F

-RSB-

we

also

have

FA

-LRB-

R

R?F

-RRB-

and

for

FA

I

we

have

FA

I

-LRB-

X

I

F

X

-RRB-

Consequently

we

have

for

FA

that

-LRB-

FA

-RRB-

X

I

F

X

Since

FA

is

a

sum

relator

we

can

identify

its

constructors

FA

o

FA

FA

o

FA

-LRB-

FA

-RRB-

ffi

FA

-LRB-

FA

-RRB-

ffi

Calculating

Functions

Monad

Decomposition

Exemplified

From

the

fact

that

-LRB-

FA

-RRB-

FA

I

we

can

conclude

that

o

FA

FA

I

ffi

FA

FA

I

ffi

Theorem

-LRB-

Monad

-RRB-

Let

F

be

an

arbitrary

relator

Then

-LRB-

FA

o

FA

-LRB-

FA

I

FA

-RRB-

F

-RRB-

is

a

monad

Theorem

-LRB-

Monad

Decomposition

-RRB-

For

all

relators

F

and

G

-LRB-

F

G

-RRB-

A

GA

ffl

-LRB-

F

ffl

GA

-RRB-

A

We

now

have

enough

mathematical

tools

to

construct

the

implementations

of

the

specs

that

R.C.

Backhouse

presents

in

-LSB-

-RSB-

as

witnesses

to

an

instantiation

of

the

last

theorem

Consider

the

following

relators

M

-LRB-

Sq

Cube

-RRB-

A

N

CubeA

P

Sq

ffl

N

Q

PA

where

Cube

R

R?R?R

and

Sq

R

R?R

With

the

instantiations

F

Sq

and

G

Cube

we

find

by

the

monad

decomposition

theorem

that

M

N

ffl

Q

One

way

to

construct

this

isomorphism

is

to

find

two

specs

and

such

that

they

witness

the

claimed

isomorphism

i.e.

such

that

ffi

-LRB-

N

ffl

Q

-RRB-

I

ffi

M

I

Calculating

Functions

Monad

Decomposition

Exemplified

In

-LSB-

-RSB-

R.C.

Backhouse

constructs

the

following

specs

that

witness

the

claimed

isomorphism

-LRB-

-LRB-

o

GA

ffi

o

KA

-RRB-

-LRB-

-LRB-

o

GA

ffi

KA

-RRB-

GA

-RRB-

-RRB-

F

G

-LRB-

-RRB-

G

-LRB-

o

-LRB-

F

G

-RRB-

A

-RRB-

K

-LRB-

F

G

-RRB-

A

ffi

-LRB-

F

G

-RRB-

A

ffi

ffi

F

-LRB-

-RRB-

G

Where

K

P

KA

Q

GA

N

H

M

F

Sq

G

Cube

The

specs

and

seem

extremely

complicated

But

are

they

really

complicated

In

the

remainder

of

this

section

we

will

demonstrate

how

to

implement

these

catamorphisms

As

we

will

see

it

is

quite

straightforward

to

implement

them

We

first

consider

and

implement

the

relators

M

N

P

and

Q

The

implementation

of

the

specs

will

then

be

quite

simple

Let

us

now

consider

the

implementation

of

relator

M

Since

we

want

a

polymorphic

implementation

we

will

consider

M

I

For

M

I

we

have

M

I

f

M

-LRB-

Sq

Cube

-RRB-

A

g

-LRB-

Sq

Cube

-RRB-

A

I

f

Definition

A

g

-LSB-

I

-LRB-

Sq

Cube

-RRB-

X

-RSB-

f

Definition

g

-LSB-

I

-LRB-

Sq

X

Cube

X

-RRB-

-RSB-

f

Definitions

Sq

and

Cube

g

-LSB-

I

-LRB-

X?X

X?X?X

-RRB-

-RSB-

We

have

seen

how

to

construct

an

implementation

for

this

relator

before

in

Chapter

The

function

from

types

to

types

and

the

map

function

of

relator

M

can

be

implemented

by

data

M

a

Om

a

Two

-LRB-

M

a

-RRB-

-LRB-

M

a

-RRB-

Three

-LRB-

M

a

-RRB-

-LRB-

M

a

-RRB-

-LRB-

M

a

-RRB-

instance

Functor

M

where

map

f

-LRB-

Om

x

-RRB-

Om

-LRB-

f

x

-RRB-

map

f

-LRB-

Two

x

y

-RRB-

Two

-LRB-

map

f

x

-RRB-

-LRB-

map

f

y

-RRB-

map

f

-LRB-

Three

x

y

z

-RRB-

Three

-LRB-

map

f

x

-RRB-

-LRB-

map

f

y

-RRB-

-LRB-

map

f

z

-RRB-

Calculating

Functions

Monad

Decomposition

Exemplified

The

constructors

of

relator

M

can

be

implemented

by

the

constructor

functions

corresponding

to

the

type

constructor

associated

with

M.

Note

that

we

simply

unfolded

the

definition

of

the

relators

Sq

and

Cube

We

could

have

implemented

M

as

a

composite

relator

but

unfolding

the

definitions

gives

a

simpler

implementation

Relator

N

can

be

implemented

in

a

similar

way

A

possible

implementation

is

given

by

data

N

a

Oq

a

Drie

-LRB-

N

a

-RRB-

-LRB-

N

a

-RRB-

-LRB-

N

a

-RRB-

instance

Functor

N

where

map

f

-LRB-

On

x

-RRB-

On

-LRB-

f

x

-RRB-

map

f

-LRB-

Drie

x

y

z

-RRB-

Drie

-LRB-

map

f

x

-RRB-

-LRB-

map

f

y

-RRB-

-LRB-

map

f

z

-RRB-

The

constructors

of

relator

N

o

N

and

N

can

be

implemented

by

the

constructor

functions

Unfolding

the

definition

of

Sq

and

using

the

implementation

of

relator

N

we

find

that

relator

P

can

be

implemented

by

data

P

a

Twee

-LRB-

N

a

-RRB-

-LRB-

N

a

-RRB-

Let

us

now

concentrate

on

relator

Q

and

consider

Q

I

For

Q

I

we

have

Q

I

f

Definition

Q

g

PA

I

f

Definition

PA

Definition

P

g

-LSB-

I

P

X

-RSB-

From

this

derivation

we

can

conclude

that

Q

I

I

P

-LRB-

Q

I

-RRB-

This

might

tempt

us

to

implement

the

function

from

types

to

types

that

comes

with

relator

Q

by

data

Q

a

Oq

a

P

-LRB-

Q

a

-RRB-

But

this

is

incorrect

Although

this

syntax

is

permitted

in

Gofer

the

two

instances

of

P

-LCB-

one

as

a

constructor

function

on

the

definition

of

the

datatype

Q

and

one

as

a

type

constructor

in

the

definition

of

the

datatype

P

-LCB-

are

definitely

not

the

same

What

can

we

do

Consider

the

last

equation

in

the

above

derivation

If

we

explicitly

use

the

fact

that

the

equality

P

Sq

ffl

N

is

a

true

equality

in

the

spec-calculus

we

get

Q

I

-LSB-

I

-LRB-

Sq

ffl

N

-RRB-

X

-RSB-

Calculating

Functions

Monad

Decomposition

Exemplified

Using

the

definition

of

Sq

we

can

simplify

this

equation

to

Q

I

-LSB-

I

-LRB-

N

X?N

X

-RRB-

-RSB-

Since

Q

is

a

composite

relator

we

can

implement

relator

Q

by

data

Q

a

Oq

a

Twee

-LRB-

N

-LRB-

Q

a

-RRB-

-RRB-

-LRB-

N

-LRB-

Q

a

-RRB-

-RRB-

instance

Functor

N

Functor

Q

where

map

f

-LRB-

Oq

a

-RRB-

Oq

-LRB-

f

a

-RRB-

map

f

-LRB-

Twee

x

y

-RRB-

Twee

-LRB-

-LRB-

map

map

-RRB-

f

x

-RRB-

-LRB-

-LRB-

map

map

-RRB-

f

y

-RRB-

Note

that

the

superclass

construction

in

the

above

implementation

is

required

to

indicate

that

there

are

two

instances

of

the

overloaded

function

map

present

in

the

implementation

The

constructors

o

Q

and

Q

can

be

implemented

by

Oq

and

Twee

Now

that

we

have

completed

the

implementations

of

the

relators

we

can

implement

the

specs

For

we

have

f

Definition

g

-LRB-

-LRB-

o

GA

ffi

o

KA

-RRB-

-LRB-

-LRB-

o

GAwffi?KA

-RRB-

GA

-RRB-

-RRB-

-LRB-

F

G

-RRB-

f

Theorem

Definition

g

-LRB-

o

GA

ffi

o

KA

-RRB-

-LRB-

-LRB-

-LRB-

o

GA

ffi

KA

-RRB-

GA

-RRB-

ffi

-LRB-

F

G

-RRB-

-RRB-

f

Definition

GA

N

KA

Q

g

-LRB-

o

N

ffi

o

Q

-RRB-

-LRB-

-LRB-

-LRB-

o

N

ffi

Q

-RRB-

N

-RRB-

ffi

-LRB-

F

G

-RRB-

-RRB-

f

fusion

g

-LRB-

o

N

ffi

o

Q

-RRB-

-LRB-

-LRB-

-LRB-

o

N

ffi

Q

-RRB-

ffi

F

-RRB-

N

ffi

G

-RRB-

f

Definition

F

and

G

g

-LRB-

o

N

ffi

o

Q

-RRB-

-LRB-

-LRB-

-LRB-

o

N

ffi

Q

-RRB-

ffi

-LRB-

-RRB-

-RRB-

N

ffi

-LRB-

-RRB-

-RRB-

From

-LRB-

-LRB-

o

GA

ffi

o

KA

-RRB-

-LRB-

-LRB-

o

GA

ffi

KA

-RRB-

GA

-RRB-

-RRB-

F

G

and

-LRB-

F

G

-RRB-

A

M

we

may

conclude

that

is

a

M-catamorphism

So

we

may

implement

by

means

of

simple

structural

recursion

over

M.

Using

this

and

the

implementations

of

the

constructors

we

may

implement

by

the

following

M

a

N

-LRB-

Q

a

-RRB-

-LRB-

Om

x

-RRB-

On

-LRB-

Oq

x

-RRB-

-LRB-

Two

x

y

-RRB-

On

-LRB-

Twee

-LRB-

x

-RRB-

-LRB-

y

-RRB-

-RRB-

-LRB-

Three

x

y

z

-RRB-

Drie

-LRB-

x

-RRB-

-LRB-

y

-RRB-

-LRB-

z

-RRB-

Calculating

Functions

Monad

Decomposition

Exemplified

Note

the

implementation

of

the

fusion

For

we

have

f

Definition

g

-LRB-

-RRB-

G

f

Theorem

g

-LRB-

ffi

G

-LRB-

-RRB-

G

-RRB-

f

Definition

g

-LRB-

ffi

G

-RRB-

f

Definition

G

Definition

Cube

g

-LRB-

ffi

-LRB-

-RRB-

-RRB-

From

-LRB-

-RRB-

G

and

GA

N

we

may

conclude

that

is

a

N-catamorphism

So

we

may

implement

by

means

of

structural

recursion

over

N.

Thus

we

may

implement

by

N

-LRB-

Q

a

-RRB-

M

a

-LRB-

On

x

-RRB-

x

-LRB-

Drie

x

y

z

-RRB-

Drie

-LRB-

x

-RRB-

-LRB-

y

-RRB-

-LRB-

z

-RRB-

Let

us

now

consider

spec

For

we

have

f

Definition

g

o

-LRB-

F

G

-RRB-

A

-LRB-

ffi

K

-RRB-

f

Definition

K

Definition

P

g

o

-LRB-

F

G

-RRB-

A

-LRB-

ffi

-LRB-

Sq

ffl

N

-RRB-

-RRB-

f

Definition

Sq

g

o

-LRB-

F

G

-RRB-

A

-LRB-

ffi

-LRB-

N

N

-RRB-

-RRB-

In

the

last

expression

we

have

N

Here

we

have

to

explicitly

use

that

a

relator

is

not

only

a

function

from

types

to

types

but

also

a

function

that

maps

morphisms

to

morphisms

may

be

implemented

by

Q

a

M

a

-LRB-

Oq

x

-RRB-

Om

x

-LRB-

Twee

x

y

-RRB-

-LRB-

map

x

-RRB-

-LRB-

map

y

-RRB-

Calculating

Functions

Monad

Decomposition

Exemplified

Two

Two

Three

Om

Om

Three

Om

Two

Om

Om

Om

Om

Two

Om

Three

Om

Om

Two

Om

Om

Figure

Elements

of

type

M

We

leave

the

implementations

of

the

specs

and

as

an

exercise

for

the

reader

When

all

specs

are

implemented

we

may

verify

that

for

all

x

M

a

and

for

all

y

N

-LRB-

Q

a

-RRB-

we

have

-LRB-

id

is

an

overloaded

identity

function

-RRB-

-LRB-

x

-RRB-

id

x

-LRB-

y

-RRB-

id

y

This

implies

that

ffi

-LRB-

N

ffl

Q

-RRB-

I

ffi

M

I

So

the

functions

and

we

implemented

do

indeed

exhibit

the

isomorphism

between

M

and

N

ffl

Q

The

structure

of

an

element

of

type

M

a

can

be

graphically

represented

by

Figure

The

structure

of

the

corresponding

element

of

type

N

-LRB-

Q

a

-RRB-

can

be

graphically

represented

by

Figure

How

can

we

verify

this

correspondence

Label

the

leaves

in

one

of

the

trees

calculate

the

prefix

traversal

of

this

tree

and

apply

the

correct

function

-LRB-

or

-RRB-

to

it

The

result

will

be

the

prefix

traversal

of

the

other

tree

The

construction

of

one

tree

from

the

other

is

very

straightforward

replace

the

constructor

Om

everywhere

by

On

Oq

the

constructor

Two

by

On

Twee

and

the

constructor

Three

by

Drie

Calculating

Functions

Summary

On

Twee

On

Twee

Drie

On

Oq

On

Oq

Drie

On

Oq

On

Twee

On

Oq

On

Oq

On

Oq

On

Oq

On

Twee

On

Oq

Drie

On

Oq

On

Oq

On

Twee

On

Oq

On

Oq

Figure

Elements

of

type

N

ffl

Q

Summary

In

this

chapter

we

have

looked

at

the

spec-calculus

counterparts

of

recursive

functions

in

functional

programming

catamorphisms

These

catamorphisms

encapsulate

the

recursion

pattern

by

means

of

a

very

elegant

and

concise

notation

In

this

chapter

we

also

discussed

how

to

implement

catamorphisms

in

general

and

we

have

discussed

several

practical

examples

Especially

we

explicitly

constructed

the

implementation

of

the

map

function

corresponding

to

the

relator

List

Exercises

x

Exercise

Prove

that

for

arbitrary

relator

F

FA

I

I

F

FA

I

Calculating

Functions

Exercises

x

Exercise

-LRB-

-RRB-

Prove

Theorem

x

Exercise

-LRB-

-RRB-

Implement

the

specs

and

Calculating

Functions

As

soon

as

men

recognise

some

similarity

between

two

things

it

is

their

custom

to

ascribe

to

each

of

them

even

in

those

respects

in

which

they

are

different

what

they

know

to

be

true

of

the

other

Ren?e

Descartes

Rules

for

the

direction

of

the

mind

Chapter

Calculating

Isomorphisms

Isomorphisms

are

a

very

interesting

subject

when

considering

types

As

we

have

seen

before

do

isomorphisms

also

play

a

significant

r

ole

in

functional

programming

In

the

previous

chapter

we

have

seen

an

isomorphism

and

we

have

implemented

two

functions

which

exhibit

that

isomorphism

But

where

did

these

functions

come

from

In

this

chapter

we

will

take

a

closer

look

at

isomorphisms

in

the

speccalculus

and

we

actually

calculate

two

isomorphisms

We

also

see

how

to

calculate

with

isomorphisms

Isomorphisms

in

the

Spec-Calculus

A

question

to

which

any

respectable

theory

of

datatypes

should

provide

immediate

answers

is

when

two

datatypes

are

isomorphic

i.e.

entirely

equivalent

modulo

implementation

details

A

subsidiary

question

is

when

one

datatype

simulates

another

This

second

question

is

in

its

own

right

but

is

also

important

to

answering

the

first

question

since

isomorphism

is

frequently

reduced

to

mutual

simulation

-LRB-

cf.

-LSB-

-RSB-

-RRB-

In

-LSB-

-RSB-

and

-LSB-

-RSB-

we

may

find

some

formal

definitions

of

the

notion

of

simulation

but

for

the

moment

we

will

content

ourselves

with

an

informal

one

If

F

and

G

are

relators

then

F

simulates

G

if

there

is

some

program

-LRB-

spec

-RRB-

henceforth

called

the

witness

that

enables

one

to

transform

all

computations

involving

G-structures

to

computations

involving

F-structures

We

will

denote

the

fact

that

F

simulates

G

by

writing

F

G

The

fact

that

witnesses

this

simulation

is

denoted

by

F

G

One

way

to

prove

that

two

relators

F

and

G

are

naturally

isomorphic

is

to

construct

two

specs

one

witnessing

that

F

simulates

G

and

one

witnessing

that

G

simulates

F

and

then

show

that

these

specs

are

each

others

reverse

This

method

is

used

by

R.C.

Backhouse

in

-LSB-

-RSB-

An

alternative

method

is

to

construct

a

witness

to

one

of

these

simulations

derive

its

Isomorphisms

in

the

Spec-Calculus

reverse

and

then

verify

that

the

latter

witnesses

the

other

simulation

In

-LSB-

-RSB-

Ed

Knapen

uses

the

last

approach

to

prove

the

isomorphism

in

-LSB-

-RSB-

In

the

previous

chapter

we

were

given

the

specs

of

this

isomorphism

and

we

implemented

these

specs

In

this

chapter

we

will

go

a

step

further

and

we

will

calculate

-LRB-

with

-RRB-

the

isomorphisms

ourselves

Until

now

we

used

a

definition

of

being

isomorphic

which

will

have

been

very

familiar

to

most

readers

In

this

chapter

however

we

are

going

to

use

a

different

definition

of

being

isomorphic

In

this

section

we

will

therefore

introduce

some

theory

on

isomorphisms

in

the

spec-calculus

The

reader

is

warned

to

read

this

section

very

carefully

since

the

theory

described

is

needed

extensively

in

the

remainder

of

this

chapter

In

Section

we

apply

this

theory

on

a

realistic

example

We

calculate

c.q.

derive

two

isomorphisms

between

the

datatypes

cons-list

and

snoc-list

Definition

-LRB-

The

Naturality

Operators

-RRB-

Let

R

and

S

be

arbitrary

specs

Then

we

define

the

relations

R

S

R

S

and

R

S

by

a.

R

S

Rffi

w

ffiS

b.

R

S

Rffi

v

ffiS

c.

R

S

Rffi

ffiS

We

call

spec

a

witness

to

these

naturalities

If

we

compare

this

definition

with

the

definition

of

the

naturality

operators

in

-LSB-

-RSB-

we

see

a

slightly

different

notation

We

have

used

the

notation

because

this

is

the

form

in

which

we

will

use

it

all

the

time

in

the

derivations

throughout

the

remainder

of

this

report

Also

we

removed

the

above

the

relations

so

that

we

can

introduce

a

notation

for

natural

isomorphism

further

on

in

this

section

that

is

more

coherent

with

other

lifted

notations

in

literature

As

functors

are

maps

between

categories

so

natural

transformations

are

maps

between

functors

I

hope

to

show

that

natural

transformations

arise

naturally

not

so

much

in

a

mathematical

setting

but

in

the

world

of

programming

Natural

transformations

are

to

be

thought

of

as

functions

not

so

much

between

objects

but

between

structures

Natural

transformations

capture

a

sort

of

-LSB-

parametric

-RSB-

polymorphism

David

E.

Rydeheard

-LSB-

-RSB-

Definition

-LRB-

Natural

Formations

-RRB-

For

arbitrary

relators

F

and

G

we

say

that

spec

a.

is

a

natural

transformation

from

F

to

G

and

write

F

G

if

and

only

if

for

all

specs

R

F

R

G

R

Calculating

Isomorphisms

Isomorphisms

in

the

Spec-Calculus

b.

is

a

natural

down-formation

from

F

to

G

and

write

F

G

if

and

only

if

for

all

specs

R

F

R

G

R

c.

is

a

natural

up-formation

from

F

to

G

and

write

F

G

if

and

only

if

for

all

specs

R

F

R

G

R

We

call

spec

a

witness

to

these

formations

Corollary

For

arbitrary

relators

F

and

G

and

all

specs

F

G

-LRB-

R

F

R

ffi

ffi

G

R

-RRB-

If

we

-LCB-

for

the

moment

-LCB-

put

on

our

operational

view

specs

we

may

say

that

a

for

which

F

R

G

R

holds

is

a

function

that

transforms

G

R-structures

into

F

R-structures

Definition

-LRB-

Natural

Isomorphism

-RRB-

Relators

F

and

G

are

said

to

be

-LRB-

naturally

-RRB-

isomorphic

if

and

only

if

there

exists

a

spec

such

that

a.

F

G

b.

ffi

-LSB-

F

I

c.

-LSB-

ffi

G

I

The

spec

itself

is

called

the

witness

to

the

isomorphism

We

denote

the

fact

that

spec

witnesses

an

isomorphism

between

relators

F

and

G

by

F

G.

Note

that

the

order

of

F

and

G

is

relevant

Theorem

For

relators

F

and

G

and

spec

F

G

equivales

the

conjunction

of

the

three

conditions

a.

F

G

b.

is

a

bijection

c.

F

I

and

G

I

Theorem

-LRB-

Basic

Naturalities

-RRB-

For

all

specs

R

S

T

and

U

all

f

g

and

all

imps

f

a.

Naturality

of

-LRB-

R?T

S?U

-RRB-

-LRB-

R?S

-RRB-

-LRB-

T

U

-RRB-

b.

Naturality

of

-LRB-

R?S

T

-RRB-

-LRB-

R?S

-RRB-

-LRB-

R?U

-RRB-

Calculating

Isomorphisms

Isomorphisms

in

the

Spec-Calculus

c.

Naturality

of

-LRB-

R+D

T+U

-RRB-

-LRB-

R?T

-RRB-

-LRB-

S

U

-RRB-

d.

Naturality

of

-LRB-

R?S

T

-RRB-

-LRB-

R

T

-RRB-

-LRB-

S

T

-RRB-

-LRB-

R?S

f

-RRB-

-LRB-

R

f

-RRB-

-LRB-

S

f

-RRB-

e.

Naturality

of

R+S

R

f.

Naturality

of

R+S

S

g.

Naturality

of

ffi

ffi

-LRB-

R?T

-RRB-

-LRB-

R?S

-RRB-

-LRB-

S

T

-RRB-

Theorem

-LRB-

Naturality

of

o

and

AE

-RRB-

For

all

specs

R

and

S

a

If

and

only

if

spec

S

is

a

total

spec

i.e.

spec

S

is

such

that

S

I

then

o

R

R?S

and

AE

R

S?R

b.

o

R

R

and

AE

R

R

c.

o

R

R?I

and

AE

R

I?R

d.

o

R

R?S

and

AE

R

S?R

As

we

can

see

from

the

last

two

theorems

there

are

some

restrictions

with

respect

to

the

use

of

these

naturality

arguments

These

restrictions

are

the

main

reason

that

proving

F

G

is

in

general

not

possible

when

only

using

naturality

arguments

Especially

not

when

there

is

a

involved

Experience

teaches

us

that

there

are

two

specific

strategies

for

proving

F

G

a.

F

G

F

G

F

R

ffi

ffi

G

R.

b.

F

G

F

G

ffi

G

F

ffi

-LSB-

A

spec

for

which

F

G

holds

is

called

a

candidate

witness

to

the

transformation

F

G

When

using

strategy

a.

we

in

fact

first

construct

a

candidate

witness

and

then

verify

that

it

is

indeed

a

witness

to

the

natural

transformation

When

using

strategy

b.

we

construct

those

two

candidate

witnesses

and

then

verify

that

they

are

each

others

inverse

Both

strategies

can

be

used

to

construct

a

witness

and

verify

that

it

is

indeed

a

correct

witness

But

what

if

we

have

a

spec

of

which

we

think

it

might

a

witness

We

will

call

such

a

witness

a

might-be

witness

In

fact

if

we

have

a

might-be

witness

we

only

have

to

verify

that

it

is

indeed

a

correct

witness

Although

this

does

not

require

the

proof

that

this

might-be

witness

is

a

candidate

witness

it

is

still

a

good

idea

to

first

prove

that

the

might-be

witness

is

indeed

a

candidate

witness

since

this

proof

is

very

easy

and

detects

very

fast

if

a

might-be

witness

is

no

candidate

witness

If

a

spec

is

no

candidate

witness

to

a

transformation

then

that

spec

Calculating

Isomorphisms

Isomorphisms

in

the

Spec-Calculus

can

never

be

a

correct

witness

to

that

transformation

Especially

when

the

might-be

witness

is

complex

which

would

result

in

a

very

difficult

proof

for

actually

proving

that

it

is

indeed

a

correct

witness

this

extra

proof

may

be

worthwhile

We

now

have

seen

quite

a

lot

of

theory

let

us

now

concentrate

on

an

example

of

the

use

of

this

theory

We

want

to

construct

a

witness

to

R

R

for

arbitrary

spec

R.

Looking

at

some

of

the

isomorphisms

in

-LSB-

-RSB-

we

suspect

AE

ffi

-LRB-

I

-RRB-

to

be

a

might-be

witness

to

this

naturality

We

will

use

the

first

strategy

for

the

proof

So

first

we

have

to

prove

that

it

is

a

good

candidate

witness

This

proof

is

as

follows

AE

ffi

-LRB-

I

-RRB-

R

R

-LRB-

f

Naturality

of

ffi

g

AE

R

Q

I

Q

R

f

Q

R

g

AE

R

R

I

R

R

-LRB-

f

Naturality

of

AE

g

I

R

R

-LRB-

f

Naturality

of

g

I

R

R

-LRB-

f

Definition

g

ffi

w

ffi

R

ffi

I

w

I

ffi

R

-LRB-

f

I

ffi

R

R

R

ffi

I

g

ffi

w

ffi

-LRB-

f

Monotonicity

of

ffi

over

w

g

w

f

Definition

g

true

We

now

have

proven

that

our

might-be

witness

is

indeed

a

correct

candidate

witness

We

now

have

to

proof

that

it

also

is

a

correct

witness

i.e.

that

R

ffi

-LRB-

AE

ffi

-LRB-

I

-RRB-

-RRB-

AE

ffi

-LRB-

I

-RRB-

ffi

-LRB-

R

-RRB-

This

proof

is

as

follows

AE

ffi

-LRB-

I

-RRB-

ffi

-LRB-

R

-RRB-

f

I

is

a

monotype

i.e.

I

I

Naturality

of

AE

i.e.

I

ffi

AE

-LRB-

I

-RRB-

g

Calculating

Isomorphisms

List

Isomorphisms

AE

ffi

-LRB-

R

-RRB-

f

Computation

rule

for

g

R

ffi

AE

ffi

-LRB-

I

-RRB-

f

is

a

monotype

i.e.

g

R

ffi

AE

ffi

-LRB-

I

-RRB-

From

the

above

derivations

we

may

conclude

the

validity

of

the

following

theorem

Theorem

-LRB-

Unit

-RRB-

For

an

arbitrary

spec

R

AE

ffi

-LRB-

I

-RRB-

R

R

This

theorem

will

be

of

great

use

in

the

next

sections

Although

there

are

many

more

interesting

natural

transformations

which

would

fit

nicely

within

the

context

of

this

chapter

we

will

only

give

you

two

more

Theorem

-LRB-

Post-distributivity

-RRB-

For

arbitrary

specs

U

V

and

R

-LRB-

-LSB-

I

-RRB-

H

-LRB-

-LSB-

I

-RRB-

-LRB-

U?R

-RRB-

-LRB-

V

R

-RRB-

-LRB-

U

V

-RRB-

R

Theorem

-LRB-

Associativity

-RRB-

Let

R

S

and

T

be

arbitrary

specs

Let

-LRB-

o

ffi

o

-RRB-

-LRB-

AE?I

-RRB-

Then

R

-LRB-

S?T

-RRB-

-LRB-

R?S

-RRB-

T

Now

we

have

all

the

mathematical

tools

we

need

to

construct

the

isomorphisms

between

the

datatypes

cons-list

and

snoc-list

In

the

remainder

of

this

chapter

we

will

derive

and

implement

two

isomorphisms

between

these

two

datatypes

List

Isomorphisms

The

datatype

join-list

-LRB-

cf.

-LSB-

-RSB-

-RRB-

in

the

Boom-hierarchy

-LRB-

cf.

-LSB-

-RSB-

-RRB-

is

one

way

to

implement

the

intuitive

idea

people

have

of

lists

In

this

section

we

will

discuss

two

other

ways

to

represent

lists

as

a

datatype

We

will

discuss

the

datatypes

cons-list

and

snoc-list

-LRB-

cf.

-LSB-

Sec.

-RSB-

-RRB-

We

will

also

show

that

these

two

datatypes

are

in

fact

isomorphic

To

do

so

we

will

construct

two

different

isomorphisms

The

first

reverse

is

an

isomorphism

that

simply

reverses

the

given

list

This

is

equivalent

to

simply

swapping

the

elements

through

the

given

list

The

second

is

a

swap-free

isomorphism

in

the

sense

that

it

does

not

simply

swap

the

elements

It

actually

changes

the

structure

Calculating

Isomorphisms

List

Isomorphisms

Introduction

A

cons-list

-LRB-

cons

is

an

abbreviation

of

construct

-RRB-

is

a

list

which

is

constructed

from

right

to

left

i.e.

new

elements

are

appended

to

the

left

In

literature

-LRB-

cf.

-LSB-

-RSB-

-RRB-

we

also

find

the

term

forward

lists

for

lists

that

are

constructed

in

this

way

An

example

of

such

a

list

is

given

by

a

-LRB-

b

-LRB-

c

nilc

-RRB-

-RRB-

A

snoc-list

is

constructed

just

the

other

way

around

-LRB-

which

explains

its

name

snoc

is

the

reverse

of

cons

-RRB-

i.e.

new

elements

are

appended

to

the

right

In

literature

-LRB-

cf.

-LSB-

-RSB-

-RRB-

we

also

find

the

term

strings

to

denote

lists

that

are

constructed

in

this

way

An

example

of

this

kind

of

list

is

given

by

-LRB-

-LRB-

nils

a

-RRB-

b

-RRB-

c

The

datatype

cons-list

over

type

R

is

the

least

solution

of

the

equation

X

X

-LRB-

R?X

-RRB-

The

cons-list

relator

will

be

denoted

by

C

So

C

R

-LRB-

R

-RRB-

where

R?X

-LRB-

R?X

-RRB-

The

datatype

snoc-list

over

type

R

is

the

least

solution

of

the

equation

X

X

-LRB-

X?R

-RRB-

The

snoc-list

relator

will

be

denoted

by

S

So

S

R

-LRB-

R

-RRB-

where

R

X

-LRB-

X?R

-RRB-

In

this

section

we

will

show

that

both

datatypes

are

isomorphic

We

will

actually

show

that

there

are

two

significantly

different

isomorphisms

Reverse

In

this

section

we

will

derive

the

first

isomorphism

between

the

datatypes

cons-list

and

snoclist

In

fact

this

isomorphism

will

transform

the

cons-list

a

-LRB-

b

-LRB-

c

nilc

-RRB-

-RRB-

into

the

snoc-list

-LRB-

-LRB-

nils

c

-RRB-

b

-RRB-

a

If

we

consider

the

tree-representations

of

these

two

lists

-LRB-

Figure

and

Figure

-RRB-

we

can

see

that

this

isomorphism

does

n't

do

much

more

than

swap

the

elements

We

then

can

also

see

the

reason

for

the

title

of

this

section

if

we

consider

the

relative

position

of

the

elements

a

b

and

c

we

get

abc

-LRB-

Figure

-RRB-

and

cba

-LRB-

Figure

-RRB-

For

all

specs

R

Calculating

Isomorphisms

List

Isomorphisms

Cons

a

Cons

b

Cons

c

Nilc

Figure

Tree

representation

of

a

-LRB-

b

-LRB-

c

nilc

-RRB-

-RRB-

Snoc

Snoc

Snoc

Nils

c

b

a

Figure

Tree

representation

of

-LRB-

-LRB-

nils

c

-RRB-

b

-RRB-

a

Calculating

Isomorphisms

List

Isomorphisms

C

R

f

Definition

C

g

-LRB-

R

-RRB-

f

Definition

R

g

-LRB-

X

R?X

-RRB-

f

is

a

binary

relator

g

-LRB-

X

R?I

ffi

I?X

-RRB-

f

Definition

-LRB-

-RRB-

g

-LRB-

I

R?I

-RRB-

f

ffl

yR

-LRB-

I

R?I

-RRB-

g

yR

Analogously

S

R

zR

where

z

-LRB-

X

-LRB-

I

X

I

-RRB-

-RRB-

So

C

S

f

Above

g

y

z

-LRB-

f

-LSB-

Theorem

-RSB-

-LRB-

I

-LSB-

-RRB-

g

f

Definition

g

-LRB-

X

Y

Y

X

-RRB-

-LRB-

X

Y

X?Y

-RRB-

-LRB-

f

ffl

ffi

Theorem

g

ffi

-LRB-

X

Y

Y

X

-RRB-

-LRB-

X

Y

X?Y

-RRB-

-LRB-

f

ffl

ffi

g

true

Theorem

Let

denote

the

binary

relator

-LRB-

X

Y

Y

X

-RRB-

let

denote

the

relator

-LRB-

X

Y

X

Y

-RRB-

and

let

spec

be

such

that

Then

Calculating

Isomorphisms

List

Isomorphisms

So

the

witness

to

the

isomorphism

C

S

is

given

by

-LRB-

I

-LRB-

-RRB-

-LSB-

-RRB-

which

is

by

-LSB-

Theorem

-RSB-

equal

to

-LRB-

I

-RRB-

-LSB-

So

-LSB-

-LRB-

I

-RRB-

If

we

now

take

ffi

-LSB-

we

can

easily

see

that

ffi

-LRB-

I

-RRB-

Using

the

fact

that

is

a

binary

relator

and

that

-LSB-

and

that

-LRB-

-RRB-

-LSB-

we

find

for

-LRB-

I

-RRB-

Let

us

now

consider

the

implementation

of

the

functions

ffi

and

As

we

can

see

from

the

definitions

is

a

S-catamorphism

and

ffi

a

C-catamorphism

Before

we

can

proceed

with

the

implementation

of

ffi

and

we

have

to

implement

the

relators

C

and

S

Since

both

are

unary

map

relators

we

can

very

easily

implement

them

by

data

ConsList

a

Nilc

Cons

-LRB-

a

-RRB-

-LRB-

ConsList

a

-RRB-

instance

Functor

ConsList

where

map

f

-LRB-

Nilc

-RRB-

Nilc

map

f

-LRB-

Cons

v

lv

-RRB-

Cons

-LRB-

f

v

-RRB-

-LRB-

map

f

lv

-RRB-

o

C

is

implemented

by

Nilc

C

is

implemented

by

Cons

data

SnocList

a

Nils

Snoc

-LRB-

SnocList

a

-RRB-

-LRB-

a

-RRB-

instance

Functor

SnocList

where

map

f

-LRB-

Nils

-RRB-

Nils

map

f

-LRB-

Snoc

lv

v

-RRB-

Snoc

-LRB-

map

f

lv

-RRB-

-LRB-

f

v

-RRB-

o

S

is

implemented

by

Nils

S

is

implemented

by

Snoc

Again

we

encounter

the

polymorphic

functions

o

AE

and

In

Chapter

we

have

seen

a

method

for

implementing

these

functions

in

a

simulated

polymorphic

way

At

this

point

we

simply

define

two

versions

of

these

functions

one

for

the

cons-lists

and

one

for

the

snoc-lists

Calculating

Isomorphisms

List

Isomorphisms

lprS

SnocList

a

SnocList

a

lprS

-LRB-

Snoc

xs

x

-RRB-

xs

rprS

SnocList

a

a

rprS

-LRB-

Snoc

xs

x

-RRB-

x

splitS

SnocList

a

a

SnocList

a

splitS

xs

x

Snoc

xs

x

splitC

a

ConsList

a

ConsList

a

splitC

x

xs

Cons

x

xs

Using

the

implementations

of

the

relators

C

and

S

the

above

functions

and

the

method

of

implementing

catamorphisms

as

described

in

Chapter

we

can

implement

by

gamma

SnocList

a

ConsList

a

gamma

-LRB-

Nils

-RRB-

Nilc

gamma

p

-LRB-

Snoc

xs

x

-RRB-

-LRB-

rprS

p

-RRB-

splitC

-LRB-

gamma

-LRB-

lprS

p

-RRB-

-RRB-

-LRB-

p

is

used

to

locally

store

the

pattern

-RRB-

We

can

implement

ffi

in

a

similar

way

If

we

take

a

closer

look

at

the

effects

of

the

different

functions

lprS

rprS

and

splitC

we

can

see

that

we

can

transform

this

implementation

in

a

more

readable

form

We

can

implement

also

by

the

function

revs

and

ffi

by

the

function

revc

where

revs

and

revc

are

implemented

by

revs

SnocList

a

ConsList

a

revs

Nils

Nilc

revs

-LRB-

Snoc

l

v

-RRB-

Cons

-LRB-

v

-RRB-

-LRB-

revs

l

-RRB-

revc

ConsList

a

SnocList

a

revc

Nilc

Nils

revc

-LRB-

Cons

v

l

-RRB-

Snoc

-LRB-

revc

l

-RRB-

-LRB-

v

-RRB-

So

the

calculated

isomorphism

really

does

n't

do

much

more

than

swap

the

elements

of

a

list

In

the

next

section

we

will

construct

another

isomorphism

between

the

datatypes

cons-list

and

snoc-list

This

isomorphism

will

not

use

any

swapping

A

swap-free

isomorphism

In

this

section

we

will

calculate

a

program

that

will

transform

the

cons-list

a

-LRB-

b

-LRB-

c

nilc

-RRB-

-RRB-

into

the

snoc-list

-LRB-

-LRB-

nils

a

-RRB-

b

-RRB-

c

If

we

consider

the

tree

representations

of

these

two

lists

-LRB-

Figure

and

Figure

-RRB-

we

can

see

that

this

isomorphism

actually

changes

the

structure

of

the

lists

So

we

are

looking

for

two

specs

and

such

that

C

S

S

C

Calculating

Isomorphisms

List

Isomorphisms

Snoc

Snoc

Snoc

Nils

a

b

c

Figure

Tree

representation

of

-LRB-

-LRB-

nils

a

-RRB-

b

-RRB-

c

In

this

section

we

will

concentrate

on

the

derivation

of

For

to

be

a

witness

to

the

isomorphism

C

S

we

would

have

to

prove

the

following

three

conditions

C

S

is

a

bijection

C

I

and

S

I

In

-LSB-

-RSB-

Bart

Gijsen

proved

this

isomorphism

We

however

will

concentrate

on

the

first

of

these

three

conditions

For

all

specs

R

C

S

f

Definition

g

C

R

S

R

-LRB-

f

ffl

-LRB-

I

ffi

-RRB-

g

-LRB-

I

ffi

-RRB-

C

R

S

R

-LRB-

f

Theorem

g

ffi

C

R

R

C

R

f

Definition

g

ffi

C

R

C

R?R

-LRB-

f

ffl

ffi

Naturality

of

g

C

R

C

R

C

R?R

-LRB-

f

Definition

oC

g

oC

C

R

C

R?R

Calculating

Isomorphisms

List

Isomorphisms

Theorem

For

all

specs

R

S

and

T

-LRB-

I

R

-RRB-

S

-LRB-

T

-RRB-

-LRB-

R

S

T

S

Proof

R

S

T

S

f

Definition

g

S

ffi

R

R

ffi

T

S

f

is

a

binary

relator

g

S

ffi

R

R

ffi

T

I

ffi

I

S

-RRB-

f

Lemma

g

S

ffi

-LRB-

I

R

-RRB-

-LRB-

I

R

ffi

T

I

-RRB-

f

Map

fusion

-LRB-

-LSB-

Lemma

-RSB-

-LSB-

-RSB-

-RRB-

T

-LRB-

T

-RRB-

g

S

ffi

-LRB-

I

R

-RRB-

-LRB-

I

R

-RRB-

ffi

-LRB-

T

-RRB-

f

Definition

g

-LRB-

I

R

-RRB-

S

-LRB-

T

-RRB-

Lemma

S

ffi

-LRB-

I

R

-RRB-

-LRB-

I

R

ffi

T

I

-RRB-

-LRB-

f

Catamorphism

fusion

-LRB-

-LSB-

Corollary

a.

-RSB-

-LSB-

-RSB-

-RRB-

U

S

V

R

R

R

ffi

T

I

F

I

-LRB-

-RRB-

-LRB-

F

-RRB-

g

S

ffi

R

R

ffi

T

I

ffi

I

S

We

will

now

continue

the

proof

by

several

short

derivations

For

we

have

C

R

C

R?R

-LRB-

f

ffl

ffi

I

-LRB-

-RRB-

ffi

ffi

C

R?R

-LSB-

-RSB-

g

C

R

R

R?C

R

R

S

-LRB-

T?R

-RRB-

-LRB-

S?T

-RRB-

R

Calculating

Isomorphisms

List

Isomorphisms

In

the

above

proof

we

use

a

very

big

step

Although

we

set

out

to

give

the

proofs

in

small

steps

we

could

n't

and

ca

n't

avoid

that

step

The

complete

proof

of

this

step

is

beyond

the

scope

of

this

report

Also

we

may

notice

that

the

typing

of

is

very

general

Shortly

we

will

instantiate

the

S

R

and

T

such

that

it

is

more

applicable

to

our

needs

Thus

-LRB-

I

oC

-RRB-

where

ffi

I

-LRB-

-RRB-

ffi

ffi

C

I?I

For

we

have

C

R

R

R?C

R

-LRB-

f

ffl

Naturality

of

g

C

R

R

C

R

R?C

R

-LRB-

f

ffl

C

g

C

R

R

C

-LRB-

f

ffl

oeC

g

oeC

C

Thus

oeC

C

where

oeC

is

a

pseudo-constructor

in

the

sense

that

it

takes

an

element

R

and

transforms

it

in

an

element

of

C.R

i.e.

it

is

the

singleton

cons-list

constructor

Before

we

consider

let

us

stop

and

take

a

closer

-LCB-

operational

-LCB-

look

at

If

is

passed

an

element

of

R

applies

oeC

to

this

element

which

will

result

in

a

singleton

cons-list

containing

only

that

element

If

however

is

passed

an

element

of

R?C

R

i.e.

an

element

of

R

together

with

an

element

of

C

R

-LRB-

a

cons-list

over

R

-RRB-

then

will

result

in

a

new

cons-list

which

is

the

result

of

appending

the

element

to

the

given

cons-list

Note

that

the

types

of

the

elements

which

may

be

passed

to

are

not

the

same

Let

us

now

continue

with

For

we

have

R

S

-LRB-

T?R

-RRB-

-LRB-

S?T

-RRB-

R

-LRB-

f

Naturality

of

ffi

ffl

ffi

g

R

S

-LRB-

T?R

-RRB-

Q

Q

-LRB-

S?T

-RRB-

R

f

Q

R

-LRB-

S?T

-RRB-

R

g

R

S

-LRB-

T?R

-RRB-

R

-LRB-

S?T

-RRB-

R

R

-LRB-

S?T

-RRB-

R

-LRB-

S?T

-RRB-

R

-LRB-

f

Naturality

of

ffl

unit

assoc

g

unit

R

R

assoc

S

-LRB-

T?R

-RRB-

-LRB-

S?T

-RRB-

R

R

-LRB-

S?T

-RRB-

R

-LRB-

S?T

-RRB-

R

-LRB-

f

Theorem

ffl

unit

AE

ffi

I

Theorem

ffl

assoc

-LRB-

o

ffi

o

-RRB-

-LRB-

AE?I

-RRB-

Theorem

ffl

distrib

-LRB-

-LSB-

I

-RRB-

H

-LRB-

-LSB-

I

-RRB-

g

Calculating

Isomorphisms

List

Isomorphisms

distrib

Thus

-LRB-

unit

assoc

-RRB-

ffi

distrib

where

unit

AE

ffi

I

assoc

-LRB-

o

ffi

o

-RRB-

-LRB-

AE?I

-RRB-

and

unit

assoc

and

where

unit

R

R

assoc

S

-LRB-

T?R

-RRB-

-LRB-

S?T

-RRB-

R

R

S

-LRB-

T?R

-RRB-

R

-LRB-

S?T

-RRB-

R

Let

us

now

instantiate

S

by

R

T

by

C

R

and

R

by

R

We

then

get

unit

R

R

assoc

R

-LRB-

C

R?R

-RRB-

-LRB-

R?C

R

-RRB-

R

R

R

-LRB-

C

R?R

-RRB-

R

-LRB-

R?C

R

-RRB-

R

If

we

want

to

implement

these

transformations

we

could

-LCB-

again

-LCB-

implement

them

in

terms

of

functions

like

lpr

rpr

and

split

We

prefer

not

to

do

so

Instead

we

will

implement

them

by

type

considerations

and

considering

the

effects

of

o

AE

and

Associating

Cons

a

-LRB-

ConsList

a

-RRB-

with

R?C

R

and

Nilc

with

we

can

implement

the

transformations

unit

and

assoc

by

unit

-LRB-

ConsList

a

b

-RRB-

b

unit

-LRB-

Nilc

x

-RRB-

x

assoc

-LRB-

ConsList

a

b

-RRB-

-LRB-

a

-LRB-

ConsList

a

b

-RRB-

-RRB-

assoc

-LRB-

Cons

l

lv

x

-RRB-

-LRB-

l

-LRB-

lv

x

-RRB-

-RRB-

Note

that

we

used

a

silent

coercion

instead

of

using

binary

type

constructors

to

implement

R

and

-LRB-

R?C

R

-RRB-

R

we

implemented

them

with

a

unary

type

constructor

on

pairs

The

transformation

has

to

be

the

sum

of

assoc

and

unit

i.e.

rho

-LRB-

Nilc

x

-RRB-

unit

-LRB-

Nilc

x

-RRB-

rho

-LRB-

Cons

v

lv

x

-RRB-

assoc

-LRB-

Cons

v

lv

x

-RRB-

Since

the

types

of

the

results

of

unit

and

assoc

are

not

the

same

we

have

to

construct

an

intermediate

datatype

such

that

it

contains

the

result

type

of

unit

and

the

result

type

of

assoc.

We

will

implement

this

intermediate

datatype

by

type

Pair

a

b

-LRB-

ConsList

a

b

-RRB-

data

IMD

a

b

Simply

b

Complex

-LRB-

a

Pair

a

b

-RRB-

For

unit

assoc

and

we

get

Calculating

Isomorphisms

List

Isomorphisms

unit

Pair

a

b

IMD

a

b

unit

-LRB-

Nilc

x

-RRB-

Simply

x

assoc

Pair

a

b

IMD

a

b

assoc

-LRB-

Cons

v

lv

x

-RRB-

Complex

-LRB-

v

-LRB-

lv

x

-RRB-

-RRB-

rho

Pair

a

b

IMD

a

b

rho

p

-LRB-

Nilc

x

-RRB-

unit

p

rho

p

-LRB-

Cons

v

lv

x

-RRB-

assoc

p

In

this

implementation

we

may

notice

two

things

ffl

First

unit

and

assoc

had

to

be

defined

on

the

entire

datatype

IMD

a

b.

ffl

Second

the

p@-part

in

the

definition

of

rho

is

used

to

locally

store

the

contents

of

the

pattern

Now

let

's

look

at

the

transformation

distrib

distrib

R

-LRB-

R?C

R

-RRB-

R

-LRB-

R?C

R

-RRB-

R

Since

C

R

-LSB-

R?X

-RSB-

we

also

have

C

R

R?C

R.

Substituting

C

R

for

R?C

R

in

the

above

expression

results

in

distrib

-LRB-

-LSB-

I

-RRB-

H

-LRB-

-LSB-

I

-RRB-

distrib

-LRB-

R

-RRB-

-LRB-

R?C

R

-RRB-

R

C

R?R

For

distrib

we

have

distrib

ffi

-LRB-

I

-RRB-

f

Definition

distrib

g

-LRB-

-LRB-

-LSB-

I

-RRB-

H

-LRB-

-LSB-

I

-RRB-

-RRB-

ffi

-LRB-

I

-RRB-

f

H

fusion

g

-LRB-

-LRB-

-LSB-

I

-RRB-

ffi

-LRB-

I

-RRB-

-RRB-

H

-LRB-

-LRB-

-LSB-

I

-RRB-

ffi

-LRB-

I

-RRB-

-RRB-

f

fusion

g

-LRB-

I?I

-RRB-

H

Similarly

we

have

distrib

ffi

-LRB-

I

-RRB-

H

-LRB-

I?I

-RRB-

This

corresponds

to

saying

that

distrib

is

in

fact

a

disjoint

case

analysis

Using

again

that

may

be

associated

with

Nilc

and

that

R?C

R

may

be

associated

with

Cons

a

-LRB-

ConsList

a

-RRB-

we

may

implement

distrib

by

the

following

Calculating

Isomorphisms

List

Isomorphisms

distrib

Pair

a

b

Pair

a

b

distrib

p

-LRB-

Nilc

x

-RRB-

p

distrib

p

-LRB-

Cons

v

lv

x

-RRB-

p

With

this

definition

for

we

have

for

-LRB-

I

oC

-RRB-

where

-LRB-

oeC

C

-RRB-

ffi

-LRB-

I

-LRB-

-RRB-

-RRB-

ffi

-LRB-

unit

assoc

-RRB-

ffi

distrib

ffi

C

I?I

If

we

take

a

closer

look

at

this

expression

for

we

see

that

the

C

I?I

part

is

simply

a

domain

restriction

and

the

-LRB-

I

-LRB-

-RRB-

-RRB-

part

is

simply

a

virtual

data

structure

-LRB-

cf.

-LSB-

-RSB-

-RRB-

When

we

consider

the

last

expression

for

we

can

rewrite

it

as

follows

f

Above

g

-LRB-

oeC

C

-RRB-

ffi

-LRB-

I

-LRB-

-RRB-

-RRB-

ffi

-LRB-

unit

assoc

-RRB-

ffi

distrib

ffi

C

I?I

f

fusion

g

-LRB-

oeC

ffi

I

-RRB-

-LRB-

C

ffi

-LRB-

-RRB-

-RRB-

ffi

-LRB-

unit

assoc

-RRB-

ffi

distrib

ffi

C

I?I

We

will

now

consider

an

implementation

of

and

From

Chapter

and

the

definition

of

oC

we

may

conclude

that

may

be

implemented

by

gamma

SnocList

a

ConsList

a

gamma

-LRB-

Nils

-RRB-

Nilc

gamma

-LRB-

Snoc

lv

v

-RRB-

delta

-LRB-

gamma

lv

-RRB-

v

Before

we

continue

with

we

first

implement

This

is

very

easy

Pair

a

b

Pair

a

b

rho

distrib

Finally

we

can

implement

our

by

delta

Identity

a

ConsList

a

a

ConsList

a

delta

l

x

case

-LRB-

-LRB-

l

x

-RRB-

-RRB-

of

Simply

x

Cons

x

Nilc

Complex

-LRB-

x

-LRB-

y

z

-RRB-

-RRB-

Cons

-LRB-

id

x

-RRB-

-LRB-

delta

y

x

-RRB-

Identity

is

a

type

class

with

one

member

function

the

function

id

which

groups

the

identity

functions

on

the

datatypes

in

our

program

If

we

now

make

the

valid

simplification

that

id

v

v

we

may

implement

by

delta

ConsList

a

a

ConsList

a

delta

l

x

case

-LRB-

-LRB-

l

x

-RRB-

-RRB-

of

Simply

x

Cons

x

Nilc

Complex

-LRB-

x

-LRB-

y

z

-RRB-

-RRB-

Cons

-LRB-

x

-RRB-

-LRB-

delta

y

x

-RRB-

Calculating

Isomorphisms

A

Class

of

Isomorphisms

If

we

take

a

closer

look

at

the

above

implementations

and

at

their

effects

we

may

notice

that

we

can

rewrite

the

implementation

of

such

that

we

can

completely

remove

the

intermediate

datatype

We

can

rewrite

the

above

implementation

as

follows

delta

ConsList

a

a

ConsList

a

delta

-LRB-

Nilc

-RRB-

x

Cons

-LRB-

x

-RRB-

-LRB-

Nilc

-RRB-

delta

-LRB-

Cons

a

b

-RRB-

x

Cons

-LRB-

a

-RRB-

-LRB-

delta

b

x

-RRB-

gamma

SnocList

a

ConsList

a

gamma

-LRB-

Nils

-RRB-

Nilc

gamma

-LRB-

Snoc

l

x

-RRB-

delta

-LRB-

gamma

l

-RRB-

x

The

functions

gamma

and

delta

exhibit

the

isomorphism

between

C

and

S.

We

however

also

need

a

function

that

exhibits

the

isomorphism

between

S

and

C

We

state

without

proof

that

the

following

two

functions

are

the

correct

implementations

of

the

functions

that

exhibit

this

isomorphism

atled

SnocList

a

ConsList

a

atled

-LRB-

Nils

-RRB-

x

singles

x

atled

-LRB-

Snoc

b

a

-RRB-

x

Snoc

-LRB-

atled

b

x

-RRB-

-LRB-

a

-RRB-

ammag

ConsList

a

ConsList

a

ammag

-LRB-

Nilc

-RRB-

Nils

ammag

-LRB-

Cons

x

l

-RRB-

atled

-LRB-

ammag

l

-RRB-

x

The

reader

may

verify

that

for

all

x

SnocList

a

and

for

all

y

ConsList

a

we

have

-LRB-

again

id

is

an

overloaded

identity

function

-RRB-

gamma

-LRB-

ammag

y

-RRB-

id

y

ammag

-LRB-

gamma

x

-RRB-

id

x

This

implies

that

ffi

C

I

ffi

S

I

This

then

implies

C

S

S

C

-LSB-

A

Class

of

Isomorphisms

In

this

chapter

we

have

demonstrated

how

to

calculate

with

isomorphisms

and

how

to

construct

witnesses

to

isomorphisms

For

two

relators

F

and

G

to

be

isomorphic

we

have

to

construct

two

specs

ffi

and

such

that

ffi

F

G

and

G

F

If

we

have

a

large

number

of

isomorphic

datatypes

in

a

program

and

if

the

witnesses

to

these

isomorphisms

are

implemented

then

we

have

a

lot

of

different

functions

-LCB-

with

different

Calculating

Isomorphisms

Summary

names

-LCB-

that

exhibit

the

isomorphic

behaviour

of

these

datatypes

What

we

would

like

to

have

is

one

polymorphic

function

that

depending

on

the

type

of

its

argument

transforms

the

argument

into

an

equivalent

element

of

an

isomorphic

datatype

In

Gofer

we

can

implement

a

function

with

this

behaviour

using

a

type

class

class

Isomorphic

b

a

Isomorphic

a

b

where

transform

a

b

In

this

implementation

we

use

the

superclass

context

indicating

that

we

can

only

have

a

function

exhibiting

the

isomorphism

between

datatype

a

and

datatype

b

if

and

only

if

there

is

also

a

function

defined

exhibiting

the

isomorphism

between

the

datatypes

b

and

a

In

fact

this

is

the

implementation

of

the

fact

that

we

need

the

two

specs

ffi

and

for

the

isomorphism

between

the

relators

F

and

G

The

fact

that

any

type

is

isomorphic

to

itself

can

be

described

by

the

following

instance

declaration

instance

Isomorphic

a

a

where

transform

x

x

For

all

other

datatypes

we

need

two

clauses

to

define

a

correct

instance

declaration

For

the

datatypes

cons-list

and

snoc-list

we

can

describe

the

isomorphism

by

the

following

instance

declarations

instance

Isomorphic

-LRB-

ConsList

a

-RRB-

-LRB-

SnocList

a

-RRB-

where

transform

x

ammag

x

instance

Isomorphic

-LRB-

SnocList

a

-RRB-

-LRB-

ConsList

a

-RRB-

where

transform

x

gamma

x

Although

these

type

classes

can

be

used

there

is

one

little

drawback

to

their

use

they

require

explicit

typing

for

the

type

inference

In

effect

this

means

that

when

using

the

function

transform

we

will

have

to

indicate

the

type

of

the

result

For

example

transform

-LRB-

Snoc

Nils

-RRB-

ConsList

Int

will

transform

the

snoc-list

Snoc

Nils

into

its

cons-list

equivalent

Cons

Nilc

This

additional

type

information

can

also

be

used

in

arbitrary

expressions

e.g.

map

-LRB-

-RRB-

-LRB-

transform

-LRB-

Snoc

Nils

-RRB-

ConsList

Int

-RRB-

Summary

In

this

chapter

we

discussed

how

to

calculate

with

isomorphisms

and

how

to

construct

specs

that

witness

isomorphisms

In

this

chapter

we

also

constructed

two

isomorphisms

between

the

datatypes

cons-list

and

snoc-list

Current

research

-LRB-

cf.

-LSB-

-RSB-

-RRB-

shows

that

the

construction

of

the

witnesses

and

the

Calculating

Isomorphisms

Exercises

proofs

can

be

done

in

a

shorter

way

than

we

have

exhibited

For

educational

reasons

however

we

have

chosen

for

these

longer

derivations

since

they

only

require

a

modest

knowledge

of

the

spec-calculus

to

verify

the

proofs

We

also

indicated

how

to

construct

a

class

of

isomorphisms

This

is

especially

useful

when

we

have

a

lot

of

isomorphisms

in

our

program

Exercises

x

Exercise

-LRB-

-RRB-

Prove

Theorem

x

Exercise

-LRB-

-RRB-

Prove

Theorem

Hint

recall

that

there

are

two

specific

strategies

for

constructing

a

witness

to

a

transformation

x

Exercise

-LRB-

-RRB-

Give

the

proof

of

Theorem

Hint

Recall

that

there

are

two

strategies

to

prove

the

fact

that

a

given

spec

is

witness

to

a

transformation

Calculating

Isomorphisms

There

must

be

a

real

and

living

doubt

and

without

this

all

discussion

is

idle

C.

Peirce

Collected

papers

of

C.S.

Peirce

Chapter

Discussion

In

this

report

we

have

thus

far

investigated

the

possibilities

of

implementing

expressions

from

the

spec-calculus

in

a

functional

programming

language

In

particular

we

investigated

the

implementation

of

relators

and

the

calculation

with

and

the

implementation

of

functional

catamorphisms

and

witnesses

to

isomorphisms

When

trying

to

construct

polymorphic

implementations

of

functions

that

are

parameterised

over

datatypes

we

encounter

several

problems

Most

of

these

problems

are

related

to

typing

issues

One

solution

to

our

typing

problems

would

be

to

explicitly

define

a

universe

containing

all

the

datatypes

we

discussed

Then

we

could

simply

implement

our

functions

on

-LRB-

parts

of

-RRB-

this

universe

But

this

is

not

really

what

we

want

There

are

of

course

other

possibilities

for

implementing

spec-expressions

One

other

method

that

is

quite

customary

among

people

who

work

with

the

spec-calculus

or

other

relational

calculi

is

to

implement

one

single

datatype

that

contains

all

elements

of

the

calculus

This

is

different

from

the

above

universe

construction

As

an

example

we

will

briefly

discuss

a

possible

implementation

for

the

spec-calculus

In

this

implementation

we

can

use

a

kind

of

and

so

that

there

are

no

typing

issues

any

more

Let

us

implement

our

spec-datatype

by

data

Point

Star

Inl

-LRB-

Point

-RRB-

Inr

-LRB-

Point

-RRB-

Pair

-LRB-

Point

-RRB-

-LRB-

Point

-RRB-

In

this

datatype

Star

represents

the

Inl

and

Inr

represent

and

respectively

The

identity

function

on

the

unit

type

may

be

implemented

by

unit

Star

Star

We

now

can

implement

the

binary

operator

by

junc

f

g

-LRB-

Inl

x

-RRB-

f

x

junc

f

g

-LRB-

Inr

x

-RRB-

g

x

Discussion

The

binary

relator

can

now

-LCB-

again

-LCB-

be

implemented

in

terms

of

the

operator

plus

f

g

-LRB-

Inl

x

-RRB-

Inl

-LRB-

f

x

-RRB-

plus

f

g

-LRB-

Inr

x

-RRB-

Inr

-LRB-

g

x

-RRB-

Indeed

notice

that

the

real

difference

with

respect

to

the

implementations

of

and

is

the

typing

of

the

results

Inl

-LRB-

f

x

-RRB-

versus

f

x

The

function

from

types

to

types

associated

with

the

binary

relator

is

implemented

by

the

binary

type

constructor

Pair

The

projection

functions

o

and

AE

may

be

implemented

by

lpr

and

rpr

respectively

where

lpr

and

rpr

are

implemented

by

lpr

-LRB-

Pair

x

y

-RRB-

x

rpr

-LRB-

Pair

x

y

-RRB-

y

The

function

that

maps

morphisms

to

morphisms

associated

with

the

binary

relator

may

be

implemented

by

the

non-recursive

map

like

function

times

which

can

be

implemented

by

times

f

g

-LRB-

Pair

x

y

-RRB-

Pair

-LRB-

f

x

-RRB-

-LRB-

f

y

-RRB-

The

operator

can

be

implemented

by

split

f

g

x

Pair

-LRB-

f

x

-RRB-

-LRB-

g

x

-RRB-

Now

in

this

setting

we

can

even

implement

one

single

function

to

implement

catamorphisms

cata

rel

spec

spec

-LRB-

rel

-LRB-

cata

rel

spec

-RRB-

-RRB-

Using

this

method

we

can

also

implement

single

functions

for

the

implementation

of

hylomorphisms

the

H

etc.

If

we

now

want

to

implement

the

relator

Nat

-LSB-

X

-RSB-

then

we

can

simply

do

this

by

f

x

unit

plus

x

nat

f

nat

This

is

a

very

short

method

of

implementing

spec-expressions

in

a

functional

programming

language

But

there

is

a

major

problem

with

the

above

method

All

input

and

output

is

to

be

defined

in

terms

of

the

datatype

Point

This

means

that

even

for

the

simplest

datatypes

one

will

need

coercion

functions

between

these

datatypes

and

the

Point

datatype

I

personally

think

that

the

method

we

have

presented

in

this

report

is

much

more

appealing

to

people

who

have

an

affinity

with

functional

programming

than

the

method

just

described

Even

with

all

its

restrictions

But

I

guess

that

the

dilemma

Samson

Abramsky

described

when

he

wrote

Discussion

Discussion

The

problem

with

the

existing

expository

literature

is

that

the

examples

are

chosen

from

the

traditional

areas

from

which

category

theory

originally

emerged

These

examples

may

not

be

familiar

to

the

computer

scientist

worse

the

possibility

for

positive

reinforcement

of

the

abstract

concepts

by

appropriate

computational

examples

is

lost

At

more

advanced

levels

the

selection

and

bias

of

material

is

influenced

by

the

intended

applications

and

computer

science

applications

are

sufficiently

different

to

the

mathematical

mainstream

to

create

another

expository

gap

Samson

Abramsky

-LSB-

-RSB-

still

holds

It

is

up

to

the

reader

to

choose

a

method

of

implementing

the

spec-expressions

to

functional

programs

they

feels

themself

attracted

to

Discussion

Discussion

Discussion

There

are

more

things

in

heaven

and

earth

Horatio

than

are

dreamt

of

in

your

philosophy

William

Shakespeare

Hamlet

I

I

hope

that

posterity

will

judge

me

kindly

not

only

as

to

the

things

which

I

have

explained

but

also

as

to

those

which

I

have

intentionally

omitted

so

as

to

leave

to

others

the

pleasure

of

discovery

Descartes

La

Geometrie

Chapter

Conclusions

and

Suggestions

for

Further

Research

In

this

report

we

have

taken

a

short

look

at

the

possibilities

for

constructing

polymorphic

implementations

of

elements

of

the

spec-calculus

in

a

functional

programming

language

We

have

seen

how

to

implement

relators

functional

catamorphisms

and

witnesses

to

isomorphisms

In

this

report

we

indicated

some

of

the

problems

that

arise

when

trying

to

implement

specexpressions

in

a

functional

programming

language

Some

of

these

problems

are

related

to

the

issues

of

isomorphism

and

polymorphism

in

functional

programming

Especially

the

fact

that

there

are

-LRB-

still

-RRB-

only

restricted

possibilities

for

the

definition

and

use

of

polymorphic

functions

in

functional

programming

languages

is

a

major

obstacle

to

the

use

of

these

languages

for

the

implementation

of

functions

that

are

parameterised

over

datatypes

The

problems

we

encountered

with

respect

to

the

typing

problems

when

implementing

general

polymorphic

functions

may

be

non-existent

in

explicitly

typed

languages

The

type

inference

algorithm

in

Gofer

is

clearly

not

strong

enough

for

our

-LRB-

exorbitant

-RRB-

needs

Therefore

we

may

be

able

to

implement

a

larger

number

of

polymorphic

functions

if

we

would

use

a

programming

language

with

explicit

typing

In

Chapter

we

discussed

an

alternative

approach

to

implementing

-LRB-

functional

-RRB-

spec-expressions

in

a

functional

programming

language

Using

this

approach

we

removed

all

typing

issues

by

considering

the

entire

spec-calculus

to

be

defined

over

one

single

datatype

The

result

is

that

using

this

approach

all

relators

can

be

implemented

almost

trivially

There

are

only

two

remaining

problems

with

this

approach

the

need

for

explicit

coercion

functions

and

the

fact

that

we

still

can

only

implement

functional

spec-expressions

In

the

spec-calculus

however

one

can

derive

programs

that

are

not

functional

These

rela

Conclusions

and

Suggestions

for

Further

Research

tional

programs

may

contain

non-deterministic

expressions

which

have

to

be

implemented

Functional

language

researchers

have

been

experimenting

with

non-deterministic

constructs

for

these

otherwise

deterministic

languages

for

some

time

now

-LRB-

cf.

-LSB-

-RSB-

-RRB-

but

they

are

still

in

development

Clearly

a

functional

programming

language

is

not

an

ideal

language

for

constructing

polymorphic

implementations

of

expressions

in

the

spec-calculus

Of

course

the

applicative

style

of

programming

is

not

a

palliative

for

all

the

ills

of

the

programming

world

any

more

than

any

other

programming

paradigm

Clearly

each

style

of

programming

has

its

own

adherents

and

is

better

for

certain

tasks

than

others

Are

there

any

alternatives

What

are

the

alternatives

There

are

several

possibilities

that

might

be

usable

for

implementing

elements

from

the

spec-calculus

in

a

systematic

way

We

can

only

mention

them

here

briefly

Further

research

will

be

necessary

to

investigate

whether

these

alternatives

actually

give

us

the

possibility

to

construct

implementations

in

an

elegant

and

concise

way

Alternatives

are

ffl

Relational

programming

Relational

programming

is

becoming

more

and

more

a

topic

in

modern

day

computing

science

Since

the

spec-calculus

is

a

relational

calculus

we

suggest

that

future

research

also

investigates

the

possibilities

of

implementing

specexpressions

in

a

relational

programming

language

like

Ruby

-LRB-

cf.

-LSB-

-RSB-

-RRB-

ffl

Categorical

programming

Since

the

spec-calculus

has

so

much

in

common

with

category

theory

we

should

also

consider

investigating

Charity

Charity

is

a

categorical

programming

language

based

on

distributive

categories

with

strong

datatypes

Distributive

categories

come

with

a

term

logic

which

can

express

most

standard

programs

and

they

are

fundamental

to

computer

science

because

they

permit

proof

by

case

analysis

and

when

strong

datatypes

are

introduced

proof

by

structural

induction

-LSB-

-RSB-

In

Charity

the

implementation

of

the

relator

C

can

be

constructed

by

data

conslist

-LRB-

a

-RRB-

X

nilc

X

cons

a

X

X

def

listmap

-LCB-

f

-RCB-

-LRB-

L

-RRB-

conslist

-LCB-

x

f

-LRB-

x

-RRB-

-RCB-

-LRB-

L

-RRB-

This

implementation

shows

clearly

that

we

can

use

a

cartesian

product

-LRB-

-RRB-

so

that

we

do

not

have

to

simulate

the

binary

operator

by

a

binary

constructor

function

Furthermore

we

can

recognise

the

defining

equation

X

R?X

in

the

implementation

Finally

we

can

observe

that

we

can

use

the

same

name

in

the

function

from

types

to

types

and

in

the

function

that

maps

functions

to

functions

just

as

in

the

spec-calculus

In

Charity

there

is

also

the

fold

function

on

left

data

which

corresponds

to

our

functional

catamorphisms

Even

with

respect

to

the

syntax

-LRB-

-RRB-

versus

-LRB-

-RRB-

Conclusions

and

Suggestions

for

Further

Research

Conclusions

and

Suggestions

for

Further

Research

ffl

Parameterised

programming

Since

in

the

spec-calculus

programs

are

constructed

which

are

parameterised

by

datatypes

it

might

also

be

a

good

idea

to

investigate

the

parameterised

programming

paradigm

as

it

is

used

in

for

instance

OBJ

OBJ

is

based

upon

a

simple

logical

system

namely

equational

logic

moreover

these

high

level

descriptions

of

what

a

program

does

actually

are

the

program

that

is

one

can

execute

them

-LSB-

-RSB-

Although

this

research

may

result

in

new

problems

or

different

restrictions

with

respect

to

the

possibility

of

implementing

our

spec-expressions

it

may

instigate

new

directions

in

research

These

new

directions

may

then

lead

us

to

programming

languages

that

provide

us

with

features

that

make

it

possible

for

us

to

implement

the

programs

that

we

derived

in

the

spec-calculus

in

an

elegant

and

concise

way

There

is

still

much

to

do

still

much

to

learn

A

wise

system

of

education

will

at

least

teach

us

how

little

man

yet

knows

and

how

much

he

has

still

to

learn

J.

Lubbock

The

pleasure

of

life

Conclusions

and

Suggestions

for

Further

Research

Conclusions

and

Suggestions

for

Further

Research

Conclusions

and

Suggestions

for

Further

Research

When

I

was

a

child

I

was

told

that

Santa

Claus

came

in

through

the

Chimney

and

that

computers

were

programmed

in

binary

code

Since

then

I

have

learned

that

programming

is

better

done

in

higher-level

languages

more

abstract

and

more

expressive

-LCB-

Xavier

Leroy

-LSB-

-RSB-

Appendix

A

Datatypes

and

Polymorphism

in

Gofer

In

this

appendix

we

included

a

short

introduction

to

datatypes

and

polymorphism

in

functional

programming

languages

and

in

particular

in

Gofer

The

method

of

defining

algebras

by

giving

sets

operations

and

axioms

satisfied

by

the

operations

is

a

familiar

one

in

mathematics

However

computer

science

has

given

rise

to

many

new

algebras

which

mathematicians

had

not

considered

These

algebras

are

called

datatypes

Walters

-LSB-

-RSB-

A.

Datatypes

In

addition

to

the

built-in

datatypes

Gofer

also

allows

the

definition

of

new

datatypes

using

declarations

of

the

form

data

DatatypeName

an

constrm

where

DatatypeName

is

the

name

of

a

new

type

constructor

of

arity

n

-LRB-

n

-RRB-

an

are

distinct

type

variables

representing

the

arguments

of

DatatypeName

and

constrm

-LRB-

m

-RRB-

describe

the

way

in

which

elements

of

the

new

datatype

are

constructed

Each

constri

can

take

two

forms

ffl

Name

typer

where

Name

is

a

previously

unused

constructor

function

name

-LRB-

i.e.

an

identifier

beginning

with

a

capital

letter

-RRB-

This

declaration

introduces

Name

as

a

new

constructor

function

of

type

typer

DatatypeName

an

A.

Type

synonyms

ffl

where

is

a

previously

unused

constructor

function

operator

-LRB-

i.e.

an

identifier

beginning

with

a

capital

letter

-RRB-

This

declaration

introduces

-LRB-

-RRB-

as

a

new

constructor

function

of

type

DatatypeName

an

Only

the

type

variables

an

may

appear

in

the

type

expressions

in

each

constri

in

the

definition

of

DatatypeName

In

Gofer

it

is

possible

to

use

the

same

name

simultaneously

as

both

a

type

constructor

and

as

a

constructor

function

Datatype

definitions

may

also

be

recursive

using

the

name

of

the

datatype

being

defined

on

the

right

hand

side

of

the

datatype

definition

Mutually

recursive

datatypes

are

also

permitted

A

data

definition

not

only

describes

a

new

type

but

it

also

implicitly

defines

constructor

functions

to

allow

creation

of

objects

of

that

type

In

addition

to

being

usable

as

constructors

on

the

right

side

of

definitions

these

functions

can

be

used

in

patterns

in

inductive

definitions

of

functions

These

algebraic

types

allow

a

user

to

express

a

large

range

of

ideas

directly

instead

of

having

to

write

a

solution

which

uses

a

perhaps

unnatural

implicit

mapping

between

reality

and

model

In

an

algebraic

datatype

definition

a

type

T

is

a

union

of

several

possible

structures

some

of

which

involve

T

itself

and

some

of

which

are

defined

in

terms

of

other

types

The

former

we

shall

call

recursive

cases

and

the

latter

atomic

The

algebraic

types

defined

with

the

data

construction

are

known

as

free

algebraic

types

This

means

two

things

ffl

Any

value

manufactured

using

the

constructor

functions

implicitly

supplied

when

the

type

was

specified

is

a

legal

value

of

the

type

ffl

A

value

manufactured

in

this

way

is

independent

of

all

other

values

of

the

type

There

are

also

datatypes

with

laws

but

these

can

not

be

implemented

in

Haskell

or

Gofer

-LRB-

cf.

-LSB-

-RSB-

-RRB-

A.

Type

synonyms

Type

synonyms

are

used

to

provide

convenient

abbreviations

for

type

expressions

A

type

synonym

is

introduced

by

a

declaration

of

the

form

type

Name

an

expansion

where

Name

is

the

name

of

a

new

type

constructor

of

arity

n

-LRB-

n

-RRB-

an

are

distinct

type

variables

representing

the

arguments

of

Name

and

expansion

is

a

type

expression

Unlike

the

datatype

declarations

described

in

the

previous

section

recursive

-LRB-

and

mutually

recursive

-RRB-

synonym

declarations

are

not

permitted

Datatypes

and

Polymorphism

in

Gofer

A.

Polymorphism

In

this

quest

the

apparition

of

the

concept

of

polymorphism

has

been

a

major

breakthrough

Polymorphism

supports

the

static

typing

of

generic

functions

pieces

of

programs

that

can

operate

on

data

of

different

types

For

instance

a

sorting

algorithm

can

work

on

arrays

of

any

type

as

long

as

a

suitable

ordering

function

between

the

array

elements

is

provided

These

generic

functions

are

important

since

they

can

naturally

be

reused

without

modification

in

many

programs

Without

polymorphism

static

typing

prohibits

this

reuse

with

polymorphism

static

typing

supports

this

reuse

while

checking

its

correctness

with

respect

to

the

types

-LCB-

Xavier

Leroy

-LSB-

-RSB-

A.

Polymorphism

Strachey

chose

the

adjectives

ad-hoc

and

parametric

to

distinguish

two

varieties

of

polymorphism

-LRB-

cf.

-LSB-

-RSB-

-RRB-

Ad-hoc

polymorphism

occurs

when

a

function

is

defined

over

several

types

acting

in

a

different

way

for

each

type

This

kind

of

polymorphism

is

also

called

overloading

A

typical

example

is

an

overloaded

print

function

which

can

print

meaningful

representations

of

elements

of

a

datatype

Parametric

polymorphism

occurs

when

a

function

is

defined

over

a

range

acting

in

the

same

way

for

each

type

i.e.

a

polymorphic

function

is

parametric

if

its

behaviour

does

not

depend

on

the

type

at

which

it

is

instantiated

-LRB-

cf.

-LSB-

-RSB-

-RRB-

A

typical

example

is

the

length

function

on

lists

which

acts

in

the

same

way

on

a

list

of

integers

and

a

list

of

strings

One

widely

accepted

approach

to

parametric

polymorphism

is

the

Hindley/Milner

type

system

which

is

used

in

languages

like

ML

Miranda

Haskell

and

Gofer

In

-LSB-

-RSB-

Philip

Wadler

and

Stephen

Blott

introduced

a

particularly

attractive

-LRB-

cf.

-LSB-

-RSB-

-RRB-

approach

to

overloading

based

on

the

use

of

type

classes

which

extend

the

Hindley/Milner

type

system

to

include

certain

kinds

of

overloading

Type

classes

permit

the

systematic

overloading

of

function

names

while

retaining

the

advantages

of

the

Hindley/Milner

system

every

expression

which

has

a

type

has

a

most

general

type

which

can

be

inferred

automatically

-LRB-

cf.

-LSB-

-RSB-

-RRB-

Like

in

Haskell

overloading

in

Gofer

is

based

around

a

system

of

type

classes

-LRB-

cf.

-LSB-

-RSB-

-RRB-

which

allows

overloaded

functions

to

be

grouped

together

into

related

groups

or

functions

Whilst

the

precise

details

of

the

approach

to

type

classes

used

by

Gofer

are

quite

different

from

those

of

Haskell

-LRB-

cf.

-LSB-

-RSB-

-RRB-

both

rely

on

the

same

basic

ideas

and

use

a

similar

syntax

for

defining

and

using

type

classes

Broadly

speaking

a

type

class

represents

a

family

of

types

-LRB-

the

instances

of

the

class

-RRB-

together

with

an

associated

set

of

member

functions

which

are

defined

for

each

instance

of

the

class

A

type

class

is

introduced

by

a

declaration

of

the

form

class

ClassName

a

where

signature

where

a

is

a

type

variable

representing

an

arbitrary

instance

of

the

class

called

ClassName

and

signature

specifies

the

names

and

types

-LRB-

involving

the

type

variable

a

-RRB-

of

each

of

the

Datatypes

and

Polymorphism

in

Gofer

A.

Polymorphism

member

functions

It

is

sometimes

useful

to

define

a

class

with

no

member

functions

in

which

case

the

signature

part

of

the

declaration

together

with

the

preceding

keyword

where

should

be

omitted

The

type

class

Eq

defined

below

is

a

standard

example

corresponding

to

the

set

of

types

whose

elements

may

be

tested

for

equality

class

Eq

a

where

-LRB-==-RRB-

-LRB-

=-RRB-

a

a

Bool

x

y

not

-LRB-

x

y

-RRB-

There

are

three

parts

to

this

definition

ffl

The

expression

Eq

a

in

the

first

line

introduces

a

name

Eq

for

the

class

and

indicates

that

the

type

variable

a

will

be

used

to

represent

an

arbitrary

instance

of

the

class

in

the

remaining

part

of

the

definition

An

expression

of

the

form

C

t

represents

the

assertion

that

the

type

t

is

an

instance

of

the

class

named

C

and

is

known

as

a

type

class

constraint

or

in

the

terminology

of

-LSB-

-RSB-

as

a

predicate

One

or

more

predicates

may

be

grouped

together

to

form

a

context

written

in

the

form

-LRB-

C

t

D

u

-RRB-

As

a

special

case

we

also

allow

a

single

predicate

to

be

used

to

denote

the

singleton

context

containing

that

predicate

ffl

The

second

line

gives

the

names

of

the

member

functions

of

the

class

written

as

-LRB-==-RRB-

and

-LRB-

=-RRB-

The

type

a

a

Bool

indicates

that

these

operators

are

defined

for

each

instance

a

of

Eq

as

functions

taking

two

arguments

of

type

a

and

returning

a

value

of

type

Bool

-LRB-

boolean

-RRB-

These

functions

are

intended

to

provide

an

equality

test

and

an

inequality

test

on

the

elements

of

each

instance

It

is

not

however

possible

to

place

any

semantic

restriction

on

the

definitions

given

in

any

particular

instance

other

than

ensuring

that

they

yield

values

of

the

correct

type

ffl

The

third

line

gives

a

default

definition

for

the

-LRB-

=-RRB-

operator

in

terms

of

-LRB-==-RRB-

so

that

in

general

only

the

latter

need

be

specified

to

define

an

instance

of

Eq

Alternative

definitions

for

-LRB-

=-RRB-

can

be

provided

in

specific

instances

if

appropriate

-LRB-

to

obtain

a

more

efficient

implementation

for

example

-RRB-

The

instances

of

a

type

class

are

defined

by

a

corresponding

form

of

instance

declaration

Instances

of

type

classes

may

also

be

defined

for

standard

and

user

defined

algebraic

datatypes

such

as

the

following

definition

of

equality

on

built-in

-LRB-

join

-RRB-

lists

instance

Eq

a

Eq

-LSB-

a

-RSB-

where

-LSB-

-RSB-

-LSB-

-RSB-

True

-LSB-

-RSB-

-LRB-

y

ys

-RRB-

False

-LRB-

x

xs

-RRB-

-LSB-

-RSB-

False

-LRB-

x

xs

-RRB-

-LRB-

y

ys

-RRB-

x

y

xs

ys

The

context

Eq

a

to

the

left

of

the

symbol

on

the

first

line

indicates

that

the

definition

of

equality

on

list

of

type

-LSB-

a

-RSB-

depends

on

the

equality

operation

on

elements

of

type

a

This

is

needed

to

evaluate

the

expression

x

y

in

the

last

line

of

the

definition

above

Datatypes

and

Polymorphism

in

Gofer

A.

Polymorphism

The

use

of

overloading

is

reflected

in

the

type

assigned

to

a

given

term

using

qualified

types

-LRB-

cf.

-LSB-

-RSB-

-RRB-

of

the

form

Con

t

where

Con

is

a

context

constraining

the

values

which

may

be

taken

by

the

type

variables

in

the

type

t.

For

example

the

full

type

of

the

equality

operator

-LRB-==-RRB-

introduced

by

the

class

declaration

in

the

previous

section

is

-LRB-==-RRB-

Eq

a

a

a

Bool

Qualified

types

can

also

appear

as

the

type

of

a

value

defined

either

directly

or

indirectly

in

terms

of

the

member

functions

of

a

class

member

Eq

a

a

-LSB-

a

-RSB-

Bool

member

x

-LSB-

-RSB-

False

member

x

-LRB-

y

ys

-RRB-

x

y

member

x

ys

subset

Eq

a

-LSB-

a

-RSB-

-LSB-

a

-RSB-

Bool

subset

xs

ys

all

-LRB-

nx

member

x

ys

-RRB-

xs

In

this

way

qualified

types

provide

a

restricted

form

of

polymorphism

so

that

for

example

the

member

and

subset

functions

can

only

be

used

with

lists

of

elements

on

which

an

equality

operator

has

been

defined

Another

useful

feature

particularly

as

a

structuring

mechanism

is

the

ability

to

define

a

hierarchy

of

classes

As

an

example

consider

the

following

declaration

which

introduces

a

class

Ord

whose

instances

are

types

with

both

strict

-LRB-

-RRB-

-LRB-

-RRB-

and

non-strict

-LRB-<=-RRB-

-LRB->=-RRB-

versions

of

an

ordering

defined

on

their

elements

class

Eq

a

Ord

a

where

-LRB-

-RRB-

-LRB-<=-RRB-

-LRB-

-RRB-

-LRB->=-RRB-

a

a

Bool

x

y

x

y

x

y

x

y

y

x

x

y

y

x

The

context

Eq

a

in

the

first

line

of

the

definition

of

Ord

indicates

that

Eq

is

a

superclass

of

Ord

every

instance

of

Ord

must

also

be

an

instance

of

Eq

For

a

more

expository

introduction

to

type

classes

the

reader

is

referred

to

-LSB-

-RSB-

and

-LSB-

-RSB-

Gofer

is

the

first

language

to

support

the

use

of

type

classes

with

multiple

parameters

-LRB-

cf.

-LSB-

-RSB-

-RRB-

This

is

an

experimental

feature

of

the

language

intended

to

make

it

possible

to

explore

the

claims

from

a

number

of

researchers

about

the

use

of

such

classes

Initial

experiments

suggest

that

multiple

parameter

type

classes

are

likely

to

lead

to

large

numbers

of

problems

with

unresolved

overloading

Ultimately

this

may

mean

that

such

classes

are

only

of

practical

use

in

explicitly

typed

languages

or

alternatively

that

a

more

powerful

and

general

defaulting

mechanism

is

required

to

support

user

controlled

overloading

resolution

The

following

declaration

introduces

a

class

Isomorphic

whose

elements

are

pairs

of

isomorphic

types

Datatypes

and

Polymorphism

in

Gofer

A.

Overloading

revisited

class

Isomorphic

b

a

Isomorphic

a

b

where

transform

a

b

The

single

member

function

transform

represents

the

isomorphism

mapping

elements

of

type

a

to

corresponding

elements

of

type

b.

Note

the

superclass

context

in

this

declaration

which

formalises

the

idea

that

for

a

to

be

isomorphic

to

b

b

has

to

be

isomorphic

to

a

The

fact

that

any

type

is

isomorphic

to

itself

can

be

described

by

the

following

instance

declaration

instance

Isomorphic

a

a

where

transform

x

x

Unfortunately

even

apparently

straightforward

examples

give

problems

with

unresolved

overloading

forcing

the

use

of

explicit

type

declarations

A.

Overloading

revisited

Many

functional

programs

use

a

map

function

to

apply

a

function

to

each

of

the

elements

in

a

given

list

The

type

and

definition

of

this

function

as

given

in

the

Gofer

standard

prelude

are

as

follows

map

-LRB-

a

b

-RRB-

-LSB-

a

-RSB-

-LSB-

b

-RSB-

map

f

-LSB-

-RSB-

-LSB-

-RSB-

map

f

-LRB-

x

xs

-RRB-

f

x

map

f

xs

It

is

well

known

that

the

map

function

satisfies

the

familiar

laws

map

id

id

map

f

map

g

map

-LRB-

f

g

-RRB-

A

category

theorist

will

recognise

these

observations

as

indicating

that

there

is

a

functor

from

types

to

types

whose

object

part

maps

any

given

type

a

to

the

built-in

-LRB-

join

-RRB-

list

type

-LSB-

a

-RSB-

and

whose

arrow

part

maps

each

function

f

a

b

to

the

function

map

f

-LSB-

a

-RSB-

-LSB-

b

-RSB-

A

functional

programmer

will

recognise

that

similar

constructions

are

also

used

with

a

wide

range

of

other

datatypes

as

illustrated

by

the

following

examples

data

Tree

a

Leaf

a

Tree

a

Tree

a

mapTree

-LRB-

a

b

-RRB-

-LRB-

Tree

a

Tree

b

-RRB-

mapTree

f

-LRB-

Leaf

x

-RRB-

Leaf

-LRB-

f

x

-RRB-

mapTree

f

-LRB-

l

r

-RRB-

mapTree

f

l

mapTree

f

r

data

Opt

a

Just

a

Nothing

mapOpt

-LRB-

a

b

-RRB-

-LRB-

Opt

a

Opt

b

-RRB-

mapOpt

f

-LRB-

Just

x

-RRB-

Just

-LRB-

f

x

-RRB-

mapOpt

f

Nothing

Nothing

Datatypes

and

Polymorphism

in

Gofer

A.

Overloading

revisited

Each

of

these

functions

has

a

similar

type

to

that

of

the

original

map

on

lists

and

also

satisfies

the

functor

laws

given

above

With

this

in

mind

it

seems

a

shame

that

we

have

to

use

different

names

for

each

of

these

variants

A

more

attractive

solution

would

allow

the

use

of

a

single

name

map

relying

on

the

types

of

the

objects

involved

to

determine

which

particular

version

of

the

map

functions

is

required

in

a

given

situation

Unfortunately

in

a

language

using

Hindley/Milner

type

inference

there

is

no

way

to

assign

a

type

to

the

map

function

that

would

allow

it

to

be

used

in

this

way

Furthermore

even

if

typing

were

not

an

issue

use

of

the

map

function

would

be

rather

limited

unless

some

additional

mechanism

was

provided

to

allow

the

definition

to

be

extended

to

include

new

datatypes

perhaps

distributed

across

a

number

of

distinct

program

files

The

ability

to

use

a

single

function

symbol

with

an

interpretation

that

depends

on

the

type

of

its

arguments

is

commonly

known

as

overloading

In

Gofer

overloading

is

implemented

using

type

classes

One

of

the

most

attractive

features

of

this

system

is

that

although

each

primitive

overloaded

operator

will

require

a

separate

definition

for

each

different

argument

type

there

is

no

need

for

these

to

be

in

the

same

program

file

Unfortunately

the

system

of

type

classes

is

not

sufficiently

powerful

-LRB-

cf.

-LSB-

-RSB-

-RRB-

to

give

a

satisfactory

treatment

of

the

map

function

to

do

so

would

require

a

class

Map

and

a

type

expression

m

-LRB-

t

-RRB-

involving

the

type

variable

t

such

that

S

f

m

-LRB-

t

-RRB-

j

t

is

a

member

of

Mapg

includes

-LRB-

at

least

-RRB-

the

types

f

-LRB-

a

b

-RRB-

-LRB-

-LSB-

a

-RSB-

-LSB-

b

-RSB-

-RRB-

-LRB-

a

b

-RRB-

-LRB-

Tree

a

Tree

b

-RRB-

-LRB-

a

b

-RRB-

-LRB-

Opt

a

Opt

b

-RRB-

a

and

b

arbitrary

types

g

The

only

possibility

is

to

take

m

-LRB-

t

-RRB-

t

and

choose

Map

as

the

set

of

types

S

for

which

the

map

function

is

required

-LRB-

we

write

map

to

avoid

conflicts

with

the

predefined

function

map

-RRB-

class

Map

t

where

map

t

instance

Map

-LRB-

-LRB-

a

b

-RRB-

-LRB-

-LSB-

a

-RSB-

-LSB-

b

-RSB-

-RRB-

-RRB-

where

instance

Map

-LRB-

-LRB-

a

b

-RRB-

-LRB-

Tree

a

Tree

b

-RRB-

-RRB-

where

instance

Map

-LRB-

-LRB-

a

b

-RRB-

-LRB-

Opt

a

Opt

b

-RRB-

-RRB-

where

Although

this

syntax

is

permitted

in

Gofer

-LRB-

But

not

in

Haskell

-RRB-

it

does

not

give

a

sufficiently

accurate

characterisation

of

the

type

of

map

to

be

of

much

use

For

example

the

principal

type

of

i

j

map

j

map

i

is

Datatypes

and

Polymorphism

in

Gofer

A.

Overloading

revisited

-LRB-

Map

-LRB-

a

c

e

-RRB-

Map

-LRB-

b

e

d

-RRB-

-RRB-

a

b

c

d

where

a

and

b

are

the

types

of

i

and

j

respectively

This

is

complicated

and

does

not

enforce

the

condition

that

i

and

j

have

function

types

Furthermore

the

type

is

ambiguous

since

the

type

variable

e

only

appears

on

the

left

hand

side

of

the

symbol

Under

these

conditions

a

well-defined

semantics

can

not

be

guaranteed

for

this

expression

A

much

better

approach

is

to

notice

that

each

of

the

types

for

which

the

map

function

is

required

is

of

the

form

map

-LRB-

a

b

-RRB-

-LRB-

f

a

f

b

-RRB-

The

variables

a

and

b

here

represent

arbitrary

types

while

f

ranges

over

the

set

of

type

constructors

for

which

a

suitable

map

function

has

been

defined

In

particular

we

would

expect

to

include

the

list

constructor

-LRB-

which

we

will

write

as

-LSB-

-RSB-

-RRB-

Tree

and

Opt

as

elements

of

this

set

which

motivated

by

our

earlier

comments

we

will

call

Functor

This

can

be

described

by

class

Functor

f

where

map

-LRB-

a

b

-RRB-

-LRB-

f

a

f

b

-RRB-

instance

Functor

-LSB-

-RSB-

where

map

f

-LSB-

-RSB-

-LSB-

-RSB-

map

f

-LRB-

x

xs

-RRB-

f

x

map

f

xs

instance

Functor

Tree

where

map

f

-LRB-

Leaf

x

-RRB-

Leaf

-LRB-

f

x

-RRB-

map

f

-LRB-

l

r

-RRB-

map

f

l

map

f

r

instance

Functor

Opt

where

map

f

-LRB-

Just

x

-RRB-

Just

-LRB-

f

x

-RRB-

map

f

Nothing

Nothing

Functor

is

an

example

of

a

constructor

class

Each

instance

of

Functor

can

be

thought

of

as

a

function

from

types

to

types

Furthermore

by

specifying

the

type

of

the

map

function

more

precisely

we

avoid

the

ambiguity

problem

mentioned

above

For

example

the

principal

type

of

i

j

map

j

map

i

is

simply

Functor

f

-LRB-

a

b

-RRB-

-LRB-

b

c

-RRB-

f

a

f

c

which

is

not

ambiguous

and

makes

the

types

of

i

and

j

as

-LRB-

a

b

-RRB-

and

-LRB-

b

c

-RRB-

respectively

For

a

more

expository

introduction

to

constructor

classes

the

reader

is

referred

to

-LSB-

-RSB-

and

-LSB-

-RSB-

Datatypes

and

Polymorphism

in

Gofer

It

is

costly

wisdom

that

is

bought

by

experience

R.

Ascham

The

Latin

Scholemaster

Each

problem

that

I

solved

became

a

rule

which

served

afterwards

to

solve

other

problems

Ren?e

Descartes

Discourse

on

the

method

of

rightly

conducting

the

reason

and

seeking

truth

in

the

field

of

science

Appendix

B

Solutions

to

Selected

Exercises

In

this

appendix

we

present

solutions

to

the

exercises

throughout

this

thesis

The

reader

is

encouraged

to

first

try

and

do

the

exercises

themself

Afterwards

they

can

then

verify

whether

their

solution

is

equivalent

to

the

one

given

Note

that

with

each

exercise

there

may

be

several

correct

solutions

B.

Solution

to

Exercise

We

are

to

give

an

implementation

of

the

relator

Tree

which

is

defined

by

Tree

R

-LSB-

R

X?X

-RSB-

Since

we

want

to

construct

a

polymorphic

implementation

we

will

consider

Tree

I

This

means

that

we

are

looking

for

the

least

solution

of

the

equation

X

X

I

X?X

Function

from

types

to

types

For

the

solution

Tree

I

we

have

Tree

I

-LRB-

ffi

I

-RRB-

-LRB-

ffi

-LRB-

Tree

I?Tree

I

-RRB-

-RRB-

Using

a

data-definition

we

may

implement

the

function

from

types

to

types

of

relator

Tree

by

data

Tree

a

Leaf

a

Branch

-LRB-

Tree

a

-RRB-

-LRB-

Tree

a

-RRB-

B.

Solution

to

Exercise

We

can

graphically

represent

the

implementation

details

by

Tree

I

ffi

R

ffi

-LRB-

Tree

I

Tree

I

-RRB-

data

Tree

a

Leaf

a

Branch

-LRB-

Tree

a

-RRB-

-LRB-

Tree

a

-RRB-

We

now

have

defined

a

type

constructor

Tree

which

implements

the

function

from

types

to

types

which

comes

with

the

relator

Tree

If

we

apply

this

type

constructor

to

a

type

then

the

result

is

a

type

in

which

all

elements

have

a

structure

that

may

graphically

represented

by

Branch

Branch

Leaf

Leaf

Branch

Branch

Branch

Leaf

Leaf

Leaf

Branch

Leaf

Leaf

The

map

function

Since

Tree

is

a

unary

map

relator

we

may

implement

the

map

function

by

means

of

an

instance

of

the

Functor

class

I.e.

instance

Functor

Tree

where

map

f

-LRB-

Leaf

v

-RRB-

Leaf

-LRB-

f

v

-RRB-

map

f

-LRB-

Branch

l

r

-RRB-

Branch

-LRB-

map

f

l

-RRB-

-LRB-

map

f

r

-RRB-

Constructors

Since

we

have

that

Tree

R

-LSB-

R

X?X

-RSB-

we

also

have

that

Tree

-LSB-

I

X?X

-RSB-

i.e.

Tree

X

I

X?X

Solutions

to

Selected

Exercises

B.

Solution

to

Exercise

Thus

the

initial

relator

of

Tree

is

a

sum

relator

and

thus

can

we

identify

the

constructors

of

relator

Tree

The

constructors

of

Tree

are

given

by

o

Tree

Tree

ffi

-LRB-

Tree

I?Tree

I

-RRB-

The

constructor

o

Tree

can

be

implemented

by

Leaf

and

the

constructor

Tree

can

be

implemented

by

Branch

The

domain

restrictions

are

implemented

by

the

types

of

these

constructor

functions

B.

Solution

to

Exercise

Theorem

For

arbitrary

relator

K

and

arbitrary

specs

R

and

S

-LRB-

-RRB-

K

R

-LRB-

S

ffi

K

-LRB-

-RRB-

K

-RRB-

Proof

-LRB-

-RRB-

K

f

Definition

-LRB-

-RRB-

K

g

-LRB-

I?K

-RRB-

f

Definition

-LRB-

I?K

-RRB-

g

-LSB-

ffi

-LRB-

I?K

X

-RRB-

-RSB-

f

Definition

I?K

g

-LSB-

ffi

I+K

X

-RSB-

f

fusion

RffiI

R

g

-LSB-

R

S

ffi

K

X

-RSB-

Since

-LRB-

-RRB-

K

is

the

least

solution

of

this

equation

we

also

have

-LRB-

-RRB-

K

R

S

ffi

K

-LRB-

-RRB-

K

Solutions

to

Selected

Exercises

B.

Solution

to

Exercise

B.

Solution

to

Exercise

ffl

For

we

have

-LRB-

F

G

-RRB-

A

ffi

Since

-LRB-

F

G

-RRB-

A

M

we

have

that

corresponds

to

one

of

the

constructors

of

relator

M

In

fact

corresponds

to

the

constructor

function

Three

ffl

For

we

have

-LRB-

F

G

-RRB-

A

ffi

ffi

F

Since

-LRB-

F

G

-RRB-

A

M

we

find

that

-LRB-

F

G

-RRB-

A

ffi

corresponds

to

the

constructor

function

Two

Consequently

we

can

implement

by

-LRB-

N

-LRB-

M

a

-RRB-

-RRB-

-LRB-

N

-LRB-

M

a

-RRB-

-RRB-

M

a

x

y

Two

-LRB-

x

-RRB-

-LRB-

y

-RRB-

In

this

implementation

we

did

not

implement

the

relator

F

but

we

simply

unfolded

its

definition

ffl

For

we

have

-LRB-

-RRB-

G

So

is

a

GA-catamorphism

i.e.

can

be

implemented

by

structural

recursion

over

GA

structures

Since

GAis

equivalent

to

N

we

have

that

can

be

implemented

over

N.

Using

the

computation

rules

for

-LRB-

-RRB-

and

the

fact

that

can

be

implemented

by

the

constructor

function

Three

we

can

implement

by

-LRB-

N

-LRB-

M

a

-RRB-

-RRB-

M

a

-LRB-

On

x

-RRB-

x

-LRB-

Drie

x

y

z

-RRB-

Three

-LRB-

x

-RRB-

-LRB-

y

-RRB-

-LRB-

z

-RRB-

B.

Solution

to

Exercise

Theorem

-LSB-

Post-distributivity

-RSB-

For

arbitrary

specs

U

V

and

R

-LRB-

-LSB-

I

-RRB-

H

-LRB-

-LSB-

I

-RRB-

-LRB-

U?R

-RRB-

-LRB-

V

R

-RRB-

-LRB-

U

V

-RRB-

R

Proof

We

will

prove

this

theorem

in

two

steps

first

we

will

prove

that

the

spec

-LRB-

-LSB-

I

-RRB-

H

-LRB-

-LSB-

I

-RRB-

is

a

candidate

witness

and

then

we

will

prove

that

it

is

indeed

a

correct

witness

Solutions

to

Selected

Exercises

B.

Solution

to

Exercise

-LRB-

-LSB-

I

-RRB-

H

-LRB-

-LSB-

I

-RRB-

-LRB-

U?R

-RRB-

-LRB-

V

R

-RRB-

-LRB-

U

V

-RRB-

R

-LRB-

f

Definition

H

g

-LRB-

-LRB-

-LSB-

I

-RRB-

-LSB-

-LRB-

-LSB-

I

-RRB-

-LSB-

-RRB-

-LSB-

-LRB-

U?R

-RRB-

-LRB-

V

R

-RRB-

-LRB-

U

V

-RRB-

R

-LRB-

f

Theorem

C.

g

-LRB-

-LSB-

I

-RRB-

-LSB-

-LRB-

-LSB-

I

-RRB-

-LSB-

-LRB-

U

V

-RRB-

R

-LRB-

U?R

-RRB-

-LRB-

V

R

-RRB-

f

-LSB-

over

ffi

-LSB-

is

idempotent

I

-LSB-

I

g

-LRB-

I

-RRB-

-LRB-

I

-RRB-

-LRB-

U

V

-RRB-

R

-LRB-

U?R

-RRB-

-LRB-

V

R

-RRB-

-LRB-

f

Naturality

of

g

I

-LRB-

U

V

-RRB-

R

U?R

I

-LRB-

U

V

-RRB-

R

V

R

-LRB-

f

Naturality

of

g

-LRB-

U

V

-RRB-

U

I

R

R

-LRB-

U

V

-RRB-

V

I

R

R

-LRB-

f

Naturality

of

Naturality

of

Definition

of

I

ffi

R

R

R

ffi

I

g

true

The

above

derivations

shows

that

the

spec

-LRB-

-LSB-

I

-RRB-

H

-LRB-

-LSB-

I

-RRB-

is

indeed

a

candidate

witness

Now

we

will

prove

that

it

is

in

fact

a

correct

witness

-LRB-

U?R

V

R

-RRB-

ffi

-LRB-

-LSB-

I

-RRB-

H

-LRB-

-LSB-

I

-RRB-

f

fusion

g

-LRB-

U?R

-RRB-

ffi

-LRB-

-LSB-

I

-RRB-

H

-LRB-

V

R

-RRB-

ffi

-LRB-

-LSB-

I

-RRB-

f

fusion

g

-LRB-

U

ffi

-LSB-

-RRB-

-LRB-

R

ffi

I

-RRB-

H

-LRB-

V

ffi

-LSB-

-RRB-

-LRB-

R

ffi

I

-RRB-

f

I

ffi

R

R

R

ffi

I

-LSB-

X

X

Y

-LSB-

Y

X

Y

g

-LRB-

-LSB-

ffi

-LRB-

U

V

-RRB-

-RRB-

-LRB-

I

ffi

R

-RRB-

H

-LRB-

-LSB-

ffi

-LRB-

U

V

-RRB-

-RRB-

-LRB-

I

ffi

R

-RRB-

f

fusion

g

-LRB-

-LSB-

I

-RRB-

ffi

-LRB-

-LRB-

U

V

-RRB-

R

-RRB-

H

-LRB-

-LSB-

I

-RRB-

ffi

-LRB-

-LRB-

U

V

-RRB-

R

-RRB-

f

H-spec

fusion

g

-LRB-

-LSB-

I

-RRB-

H

-LRB-

-LSB-

I

-RRB-

ffi

-LRB-

-LRB-

U

V

-RRB-

R

-RRB-

Solutions

to

Selected

Exercises

B.

Solution

to

Exercise

B.

Solution

to

Exercise

Theorem

-LSB-

Associativity

-RSB-

Let

R

S

and

T

be

arbitrary

specs

Let

-LRB-

o

ffi

o

-RRB-

-LRB-

AE?I

-RRB-

and

let

-LRB-

I?o

-RRB-

-LRB-

AE

ffi

AE

-RRB-

Then

R

-LRB-

S?T

-RRB-

-LRB-

R?S

-RRB-

T

Proof

Since

the

spec

contains

a

we

will

not

be

able

to

use

the

proof

strategy

we

used

in

the

previous

answer

We

will

have

to

use

the

second

proof

strategy

We

will

therefore

first

proof

the

following

lemma

Lemma

Let

R

S

and

T

be

arbitrary

specs

Let

-LRB-

o

ffi

o

-RRB-

-LRB-

AE?I

-RRB-

Then

R

-LRB-

S?T

-RRB-

-LRB-

R?S

-RRB-

T

Proof

R

-LRB-

S?T

-RRB-

-LRB-

R?S

-RRB-

T

f

Definition

g

-LRB-

o

ffi

o

-RRB-

-LRB-

AE?I

-RRB-

R

-LRB-

S?T

-RRB-

-LRB-

R?S

-RRB-

T

-LRB-

f

Naturality

of

g

o

ffi

o

R

-LRB-

R?S

-RRB-

T

AE?I

S?T

-LRB-

R?S

-RRB-

T

-LRB-

f

Naturality

of

o

ffi

AE

g

AE?I

S?T

-LRB-

R?S

-RRB-

T

-LRB-

f

Naturality

of

g

AE

S

R?S

I

T

T

-LRB-

f

Naturality

of

AE

Definition

of

g

T

ffi

I

w

I

ffi

T

-LRB-

f

T

ffi

I

T

I

ffi

T

g

true

From

the

above

lemma

we

may

conclude

that

R

-LRB-

S?T

-RRB-

-LRB-

R?S

-RRB-

T

Analogously

we

may

conclude

that

-LRB-

R?S

-RRB-

T

R

-LRB-

S?T

-RRB-

Solutions

to

Selected

Exercises

B.

Solution

to

Exercise

As

a

result

of

Theorem

C.

we

find

-LSB-

-LRB-

R?S

-RRB-

T

R

-LRB-

S?T

-RRB-

-LSB-

R

-LRB-

S?T

-RRB-

-LRB-

R?S

-RRB-

T

So

if

we

can

prove

-LSB-

then

we

may

conclude

that

R

-LRB-

S?T

-RRB-

-LRB-

R?S

-RRB-

T

-LSB-

f

Definition

g

-LRB-

-LRB-

I?o

-RRB-

-LRB-

AE

ffi

AE

-RRB-

-RRB-

-LSB-

f

Definition

g

-LRB-

o

-LSB-

ffi

-LRB-

I?o

-RRB-

u

AE

-LSB-

ffi

AE

ffi

AE

-RRB-

-LSB-

f

Definition

g

-LRB-

o

-LSB-

ffi

-LRB-

I

ffi

o

o

ffi

AE

-RRB-

u

AE

-LSB-

ffi

AE

ffi

AE

-RRB-

-LSB-

f

Definition

R

ffi

I

R

g

-LRB-

o

-LSB-

ffi

-LRB-

o

-LSB-

ffi

o

u

AE

-LSB-

ffi

o

ffi

AE

-RRB-

u

AE

-LSB-

ffi

AE

ffi

AE

-RRB-

-LSB-

f

o

-LSB-

is

a

co-imp

Theorem

g

-LRB-

o

-LSB-

ffi

o

-LSB-

ffi

o

u

o

-LSB-

ffi

AE

-LSB-

ffi

o

ffi

AE

u

AE

-LSB-

ffi

AE

ffi

AE

-RRB-

-LSB-

f

-LSB-

over

u

g

-LRB-

o

-LSB-

ffi

o

-LSB-

ffi

o

-RRB-

-LSB-

u

-LRB-

o

-LSB-

ffi

AE

-LSB-

ffi

o

ffi

AE

-RRB-

-LSB-

u

-LRB-

AE

-LSB-

ffi

AE

ffi

AE

-RRB-

-LSB-

f

-LSB-

over

ffi

g

o

-LSB-

ffi

o

-LSB-

-LSB-

ffi

o

-LSB-

-LSB-

u

AE

-LSB-

ffi

o

-LSB-

ffi

AE

-LSB-

-LSB-

ffi

o

-LSB-

-LSB-

u

AE

-LSB-

ffi

AE

-LSB-

ffi

AE

-LSB-

-LSB-

f

-LSB-

is

idempotent

g

o

-LSB-

ffi

o

ffi

o

u

AE

-LSB-

ffi

o

-LSB-

ffi

AE

ffi

o

u

AE

-LSB-

ffi

AE

-LSB-

ffi

AE

f

AE

-LSB-

is

a

co-imp

g

o

-LSB-

ffi

o

ffi

o

u

AE

-LSB-

ffi

-LRB-

o

-LSB-

ffi

AE

ffi

o

u

AE

-LSB-

ffi

AE

-RRB-

f

Definition

g

o

ffi

o

-LRB-

o

-LSB-

ffi

AE

ffi

o

u

AE

-LSB-

ffi

AE

-RRB-

f

Definition

g

o

ffi

o

-LRB-

AE

ffi

o

AE

-RRB-

f

I

ffi

R

R

g

o

ffi

o

-LRB-

AE

ffi

o

I

ffi

AE

-RRB-

Solutions

to

Selected

Exercises

B.

Solution

to

Exercise

f

Definition

g

o

ffi

o

-LRB-

AE?I

-RRB-

f

Definition

g

B.

Solution

to

Exercise

Theorem

Let

denote

the

binary

relator

-LRB-

X

Y

Y

X

-RRB-

let

denote

the

relator

-LRB-

X

Y

X?Y

-RRB-

and

let

spec

be

such

that

Then

Proof

If

we

want

to

conclude

that

we

have

to

prove

-LRB-

see

Definition

-RRB-

a.

b.

ffi

-LSB-

I?I

and

c.

-LSB-

ffi

I?I

As

we

have

seen

before

there

are

two

different

strategies

for

proving

Since

there

is

a

involved

here

we

use

the

second

strategy

i.e.

ffi

ffi

-LSB-

for

ffi

Lemma

-LSB-

-RSB-

For

all

specs

R

and

S

f

Definition

g

R

S

R

S

f

Definition

g

S

R

R

S

f

Definition

g

S

R

R

S

-LRB-

f

Naturality

of

g

Solutions

to

Selected

Exercises

B.

Solution

to

Exercise

AE

S

R

S

o

R

R

S

-LRB-

f

Naturality

of

o

Naturality

of

AE

g

true

Lemma

-LSB-

ffi

-RSB-

For

all

specs

R

and

S

ffi

f

Definition

g

ffi

R

S

R

S

f

Definition

g

ffi

R

S

S

R

f

ffl

ffi

g

R

S

S

R

-LRB-

f

Naturality

of

g

AE

R

S

R

o

S

S

R

-LRB-

f

Naturality

of

o

Naturality

of

AE

g

true

Lemma

-LSB-

ffi

-LSB-

-RSB-

We

have

to

prove

ffi

-LSB-

i.e.

we

have

to

prove

that

-LRB-

-RRB-

-LSB-

-LRB-

-RRB-

-LSB-

f

Definition

g

-LRB-

o

-LSB-

ffi

AE

u

AE

-LSB-

ffi

o

-RRB-

-LSB-

f

-LSB-

over

u

g

-LRB-

o

-LSB-

ffi

AE

-RRB-

-LSB-

u

-LRB-

AE

-LSB-

ffi

o

-RRB-

-LSB-

f

Symmetry

of

u

g

-LRB-

AE

-LSB-

ffi

o

-RRB-

-LSB-

u

-LRB-

o

-LSB-

ffi

AE

-RRB-

-LSB-

f

-LSB-

over

ffi

-LSB-

is

idempotent

g

o

-LSB-

ffi

AE

u

AE

-LSB-

ffi

o

f

Definition

g

Solutions

to

Selected

Exercises

B.

Solution

to

Exercise

So

from

the

above

three

lemmas

we

may

conclude

that

This

leaves

us

with

the

two

proof

obligations

ffi

-LSB-

I

I

and

-LSB-

ffi

I?I

ffi

-LSB-

f

ffi

-LSB-

ffi

-LSB-

is

idempotent

g

ffi

f

Definition

g

-LRB-

-RRB-

ffi

-LRB-

-RRB-

f

imp.AE

imp.o

imp

-LRB-

-RRB-

fusion

g

AE

ffi

-LRB-

-RRB-

o

ffi

-LRB-

-RRB-

f

Composition

Rules

for

g

o

ffi

AE

AE

ffi

o

f

-LSB-

Theorem

-RSB-

i.e.

o

AE

I?I

g

o

ffi

-LRB-

I?I

-RRB-

AE

ffi

-LRB-

I?I

-RRB-

f

Definition

g

o

-LSB-

ffi

o

ffi

-LRB-

I?I

-RRB-

u

AE

-LSB-

ffi

AE

ffi

-LRB-

I?I

-RRB-

f

-LSB-

Lemma

-RSB-

g

-LRB-

I

-RRB-

ffi

-LRB-

I?I

-RRB-

u

-LRB-

I

-RRB-

ffi

-LRB-

I?I

-RRB-

f

fusion

I

ffi

R

R

R

ffi

I

g

I

u

I

f

u

abide

law

g

I

u

u

I

f

I

v

g

I?I

f

Definition

g

I?I

Solutions

to

Selected

Exercises

B.

Solution

to

Exercise

Since

-LSB-

we

also

have

-LSB-

ffi

I?I

i.e.

-LSB-

ffi

I?I

So

we

may

conclude

that

indeed

God

gives

you

a

problem

and

He

wants

you

to

figure

it

out

E.

Magic

Johnson

Proving

by

law

teaching

by

example

and

learning

by

doing

Solutions

to

Selected

Exercises

B.

Solution

to

Exercise

Solutions

to

Selected

Exercises

Appendix

C

Additional

Theorems

In

this

appendix

we

present

some

theorems

along

with

their

proofs

that

can

not

be

found

in

-LSB-

-RSB-

or

-LSB-

-RSB-

but

which

are

used

in

this

thesis

If

we

used

one

of

these

theorems

in

this

report

we

did

not

refer

to

this

appendix

Definition

C.

-LRB-

N

-RRB-

For

arbitrary

specs

P

and

Q

P

N

Q

-LRB-

P

-LSB-

Q

-LSB-

-RRB-

-LSB-

Definition

C.

-LRB-

H

-RRB-

For

arbitrary

specs

P

and

Q

P

H

Q

-LRB-

P

-LSB-

Q

-LSB-

-RRB-

-LSB-

Theorem

C.

-LRB-

N

fusion

-RRB-

For

arbitrary

specs

P

Q

R

and

S

-LRB-

P

N

Q

-RRB-

ffi

-LRB-

R

S

-RRB-

-LRB-

P

ffi

R

-RRB-

N

-LRB-

Q

ffi

S

-RRB-

Proof

-LRB-

P

N

Q

-RRB-

ffi

-LRB-

R

S

-RRB-

f

Definition

N

g

-LRB-

P

-LSB-

Q

-LSB-

-RRB-

-LSB-

ffi

-LRB-

R

S

-RRB-

f

-LSB-

over

ffi

-LSB-

is

idempotent

g

-LRB-

-LRB-

R

S

-RRB-

-LSB-

ffi

-LRB-

P

-LSB-

Q

-LSB-

-RRB-

-LSB-

-RRB-

-LSB-

Additional

Theorems

f

is

a

binary

relator

g

-LRB-

-LRB-

R

-LSB-

S

-LSB-

-RRB-

ffi

-LRB-

P

-LSB-

Q

-LSB-

-RRB-

-RRB-

-LSB-

f

fusion

g

-LRB-

-LRB-

R

-LSB-

ffi

P

-LSB-

-RRB-

-LRB-

S

-LSB-

ffi

Q

-LSB-

-RRB-

-RRB-

-LSB-

f

-LSB-

over

ffi

g

-LRB-

-LRB-

P

ffi

R

-RRB-

-LSB-

-LRB-

Q

ffi

S

-RRB-

-LSB-

-RRB-

-LSB-

f

Definition

N

g

-LRB-

P

ffi

R

-RRB-

N

-LRB-

Q

ffi

S

-RRB-

Theorem

C.

-LRB-

H-spec

fusion

-RRB-

For

arbitrary

specs

R

S

and

T

-LRB-

R

H

S

-RRB-

ffi

T

-LRB-

R

ffi

T

-RRB-

H

-LRB-

S

ffi

T

-RRB-

Proof

-LRB-

R

H

S

-RRB-

ffi

T

f

Definition

H

g

-LRB-

R

-LSB-

S

-LSB-

-RRB-

-LSB-

ffi

T

f

-LSB-

over

ffi

-LSB-

is

idempotent

g

-LRB-

T

-LSB-

ffi

-LRB-

R

-LSB-

S

-LSB-

-RRB-

-RRB-

-LSB-

f

fusion

g

-LRB-

-LRB-

T

-LSB-

ffi

R

-LSB-

-RRB-

-LRB-

T

-LSB-

ffi

S

-LSB-

-RRB-

-RRB-

-LSB-

f

-LSB-

over

ffi

g

-LRB-

-LRB-

R

ffi

T

-RRB-

-LSB-

-LRB-

S

ffi

T

-RRB-

-LSB-

-RRB-

-LSB-

f

Definition

H

g

-LRB-

R

ffi

T

-RRB-

H

-LRB-

S

ffi

T

-RRB-

Theorem

C.

-LRB-

H

fusion

-RRB-

For

arbitrary

specs

P

Q

R

and

S

-LRB-

P

Q

-RRB-

ffi

-LRB-

R

H

S

-RRB-

-LRB-

P

ffi

R

-RRB-

H

-LRB-

Q

ffi

S

-RRB-

Proof

Additional

Theorems

Additional

Theorems

-LRB-

P

Q

-RRB-

ffi

-LRB-

R

H

S

-RRB-

f

-LSB-

over

ffi

g

-LRB-

-LRB-

R

H

S

-RRB-

-LSB-

ffi

-LRB-

P

Q

-RRB-

-LSB-

-RRB-

-LSB-

f

Definition

H

g

-LRB-

-LRB-

R

-LSB-

S

-LSB-

-RRB-

-LSB-

-LSB-

ffi

-LRB-

P

Q

-RRB-

-LSB-

-RRB-

-LSB-

f

R

-LSB-

-LSB-

R

is

a

binary

relator

g

-LRB-

-LRB-

R

-LSB-

S

-LSB-

-RRB-

ffi

-LRB-

P

-LSB-

Q

-LSB-

-RRB-

-RRB-

-LSB-

f

fusion

g

-LRB-

-LRB-

R

-LSB-

ffi

P

-LSB-

-RRB-

-LRB-

S

-LSB-

ffi

Q

-LSB-

-RRB-

-RRB-

-LSB-

f

-LSB-

over

ffi

g

-LRB-

-LRB-

P

ffiR

-RRB-

-LSB-

-LRB-

QffiS

-RRB-

-LSB-

-RRB-

-LSB-

f

Definition

H

g

-LRB-

P

ffi

R

-RRB-

H

-LRB-

Q

ffi

S

-RRB-

Theorem

C.

For

arbitrary

relators

F

and

G

F

G

-LSB-

G

F

Proof

F

G

f

Definition

g

-LRB-

R

F

R

G

R

-RRB-

f

Definition

g

-LRB-

R

F

R

ffi

w

ffi

G

R

-RRB-

f

-LSB-

over

ffi

-LSB-

is

idempotent

g

-LRB-

R

-LRB-

-LSB-

ffi

-LRB-

F

R

-RRB-

-LSB-

-RRB-

-LSB-

w

-LRB-

-LRB-

G

R

-RRB-

-LSB-

ffi

-LSB-

-RRB-

-LSB-

-RRB-

f

F

and

G

are

relators

i.e.

-LRB-

F

R

-RRB-

-LSB-

F

-LRB-

R

-LSB-

-RRB-

g

-LRB-

R

-LRB-

-LSB-

ffi

F

R

-LSB-

-RRB-

-LSB-

w

-LRB-

G

R

-LSB-

ffi

-LSB-

-RRB-

-LSB-

-RRB-

f

P

v

Q

P

-LSB-

v

Q

-LSB-

g

Additional

Theorems

Additional

Theorems

-LRB-

R

-LSB-

ffi

F

R

-LSB-

w

G

R

-LSB-

ffi

-LSB-

-RRB-

f

P

v

Q

Q

w

P

g

-LRB-

R

G

R

-LSB-

ffi

-LSB-

v

-LSB-

ffi

F

R

-LSB-

-RRB-

f

For

all

specs

R

there

is

a

spec

R

-LSB-

g

-LRB-

S

G

S

ffi

-LSB-

v

-LSB-

ffi

F

S

-RRB-

f

Definition

g

-LRB-

S

-LSB-

G

S

F

S

-RRB-

f

Definition

g

-LSB-

G

F

Corollary

For

arbitrary

relators

F

and

G

F

G

-LSB-

G

F

Additional

Theorems

Bibliography

-LSB-

-RSB-

Mart

n

Abadi

Luca

Cardelli

and

Pierre-Louis

Curien

Formal

parametric

polymorphism

In

Conference

Record

of

the

th

Annual

ACM

SIGPLAN

SIGACT

Symposium

on

Principles

of

Programming

Languages

Charleston

South

Carolina

January

pages

-LCB-

ACM

Press

-LSB-

-RSB-

Samson

Abramsky

and

Thomas

P.

Jensen

A

relational

approach

to

strictness

analysis

for

higher-order

polymorphic

functions

In

Conference

Record

of

the

th

Annual

ACM

Symposium

on

Principles

of

Programming

Languages

Orlando

Florida

January

pages

-LCB-

ACM

Press

-LSB-

-RSB-

R.C.

Backhouse

Monad

Decomposition

Department

of

Mathematics

and

Computing

Science

Eindhoven

University

of

Technology

November

-LSB-

-RSB-

R.C.

Backhouse

A

Constructive

Proof

of

an

Axiom

of

Regular

Algebra

April

-LSB-

-RSB-

R.C.

Backhouse

Constructive

Lattice

Theory

Department

of

Mathematics

and

Computing

Science

Eindhoven

University

of

Technology

July

-LSB-

-RSB-

R.C.

Backhouse

H.

Doornbos

and

P.

Hoogendijk

Commuting

Relators

In

Lecture

Notes

of

the

STOP

Summerschool

on

Constructive

Algorithmics

Part

-LSB-

-RSB-

Richard

S.

Bird

and

Oege

de

Moor

All

Monotonic

Functors

are

Relators

In

Lecture

Notes

of

the

STOP

Summerschool

on

Constructive

Algorithmics

Part

September

-LSB-

-RSB-

Richard

S.

Bird

and

Oege

de

Moor

Between

Dynamic

Programming

and

Greedy

Data

Compression

In

Lecture

Notes

of

the

STOP

Summerschool

on

Constructive

Algorithmics

Part

September

-LSB-

-RSB-

R.C.

Backhouse

P.

Hoogendijk

T.S.

Voermans

and

J.

van

der

Woude

A

Relational

Theory

of

Datatypes

Part

II

In

Lecture

Notes

of

the

STOP

Summerschool

on

Constructive

Algorithmics

Part

-LSB-

-RSB-

Richard

S.

Bird

An

introduction

to

the

theory

of

lists

In

M.

Broy

editor

Logic

of

Programming

and

Calculi

of

Discrete

Design

volume

of

NATO

ASI

Series

Springer-Verlag

BIBLIOGRAPHY

-LSB-

-RSB-

Robin

Cockett

and

Tom

Fukushima

About

Charity

Department

of

Computer

Science

University

of

Calgary

May

-LSB-

-RSB-

A.J.T.

Davie

An

Introduction

to

Functional

Programming

Systems

using

Haskell

volume

of

Cambridge

Computer

Science

Texts

Cambridge

University

Press

-LSB-

-RSB-

Bart

Gijsen

Constructive

Regular

Algebra

in

the

Spec-Calculus

Graduating

Dissertation

Department

of

Mathematics

and

Computing

Science

Eindhoven

University

of

Technology

To

appear

November

-LSB-

-RSB-

Joseph

Goguen

Parameterized

Programming

Center

for

the

Study

of

Language

and

Information

Ventura

Hall

Stanford

University

August

Report

No

CSLI

-LSB-

H

-RSB-

Paul

Hudak

et

al.

Report

on

the

programming

language

Haskell

a

non-strict

purely

functional

language

-LRB-

version

-RRB-

In

Paul

Hudak

Jospeh

H.

Fasel

Simon

L.

Peyton

Jones

and

Philip

Wadler

editors

ACM

Sigplan

Notices

Special

Issue

on

the

Functional

Programming

Language

Haskell

May

-LSB-

-RSB-

Paul

Hudak

and

Joseph

H.

Fasel

A

Gentle

Introduction

to

Haskell

In

Paul

Hudak

Jospeh

H.

Fasel

Simon

L.

Peyton

Jones

and

Philip

Wadler

editors

ACM

Sigplan

Notices

Special

Issue

on

the

Functional

Programming

Language

Haskell

May

-LSB-

-RSB-

John

Hughes

and

John

O'Donnel

Expressing

and

reasoning

about

nondeterministic

functional

programs

In

Kei

Davis

and

John

Hughes

editors

Functional

Programming

Proceedings

of

the

Glasgow

Workshop

August

Fraserburgh

Scotland

Workshops

in

computing

Springer-Verlag

British

Computer

Society

-LSB-

-RSB-

Graham

Hutton

Between

functions

and

relations

in

calculating

programs

PhD

thesis

Univeristy

of

Glasgow

October

-LSB-

-RSB-

Johan

Jeuring

Theories

for

Algorithm

Calculation

PhD

thesis

Utrecht

University

February

-LSB-

-RSB-

Mark

P.

Jones

Introduction

to

Gofer

included

as

part

of

the

Gofer

distribution

September

-LSB-

-RSB-

Mark

P.

Jones

Computing

with

lattices

An

application

of

type

classes

Journal

of

Functional

Programming

-LRB-

-RRB-

-LCB-

October

-LSB-

-RSB-

Mark

P.

Jones

Qualified

Types

Theory

and

Practice

PhD

thesis

Programming

Research

Group

Oxford

University

Computing

Laboratory

July

-LSB-

-RSB-

Mark

P.

Jones

A

theory

of

qualified

types

In

Proceedings

of

the

European

symposium

on

programming

Rennes

France

Lecture

Notes

in

Computer

Science

Springer-Verlag

-LSB-

-RSB-

Mark

P.

Jones

Gofer

release

notes

February

BIBLIOGRAPHY

BIBLIOGRAPHY

-LSB-

-RSB-

Mark

P.

Jones

A

system

of

constructor

classes

overloading

and

implicit

higher-order

polymorphism

In

Proceedings

of

the

th

ACM

Conference

on

Functional

Programming

Languages

and

Computer

Architecture

Copenhagen

Denmark

ACM

Press

June

-LSB-

-RSB-

Ed

Knapen

A

calculated

witness

July

-LSB-

-RSB-

Xavier

Leroy

Polymorphic

Typing

of

an

Algorithmic

Language

Institut

National

de

Recherche

en

Informatique

et

en

Automatique

-LRB-

INRIA

-RRB-

Rocquencourt

France

October

-LSB-

-RSB-

Grant

Malcolm

Homomorphisms

and

promotability

In

J.L.A.

van

de

Snepscheut

editor

Conference

on

the

Mathematics

of

Program

Construction

volume

of

Lecture

Notes

in

Computer

Science

pages

-LCB-

SpringerVerlag

-LSB-

-RSB-

Austin

Melton

Bernd

S.W.

Schr?oder

and

George

E.

Strecker

Connections

In

S.

Brookes

M.

Main

A.

Melton

M.

Mislove

and

D.

Schmidt

editors

Mathematical

Foundations

of

Programming

Semantics

th

International

Conference

Pittsburgh

Pennsylvania

March

Proceedings

volume

of

Lecture

Notes

in

Computer

Science

Springer-Verlag

-LSB-

-RSB-

Tobias

Nipkov

and

Christian

Prehofer

Type

checking

type

classes

In

Conference

Record

of

the

th

Annual

ACM

SIGPLAN

SIGACT

Symposium

on

Principles

of

Programming

Languages

Charleston

South

Carolina

January

pages

-LCB-

ACM

Press

-LSB-

-RSB-

David

Pitt

Samson

Abramsky

Axel

Poign?e

and

David

Rydeheard

Category

Theory

and

Computer

Programming

Tutorial

and

Workshop

Guildford

U.K.

September

Proceedings

volume

of

Lecture

Notes

in

Computer

Science

Springer-Verlag

-LSB-

-RSB-

Axel

Poign?e

Elements

of

categorical

reasoning

products

and

coproducts

and

some

other

-LRB-

co

-RRB-

limits

In

David

Pitt

Samson

Abramsky

Axel

Poign?e

and

David

Rydeheard

editors

Category

Theory

and

Computer

Programming

Tutorial

and

Workshop

Guildford

U.K.

September

Proceedings

Lecture

Notes

in

Computer

Science

Springer-Verlag

-LSB-

-RSB-

David

E.

Rydeheard

Functors

and

natural

transformations

In

David

Pitt

Samson

Abramsky

Axel

Poign?e

and

David

Rydeheard

editors

Category

Theory

and

Computer

Programming

Tutorial

and

Workshop

Guildford

U.K.

September

Proceedings

Lecture

Notes

in

Computer

Science

SpringerVerlag

-LSB-

-RSB-

D.

Sands

Calculi

for

Time

Analysis

of

Functional

Programs

PhD

thesis

Imperial

College

September

-LSB-

-RSB-

Doaitse

Swierstra

and

Oege

de

Moor

Virtual

Data

Structures

Department

of

Computing

Science

Utrecht

University

Programming

Research

Group

Oxford

University

Computing

Laboratory

BIBLIOGRAPHY

BIBLIOGRAPHY

-LSB-

-RSB-

M.

Sheeran

Ruby

-LCB-

a

language

of

relations

and

higher-order

functions

In

G.

Birtwistle

editor

Proceedings

of

the

Banff

workshop

on

hardware

verification

Springer-Verlag

-LSB-

-RSB-

Philip

Wadler

Monads

for

functional

programming

In

M.

Broy

editor

Program

Design

Calculi

Proceedings

of

the

Marktoberdorf

Summer

School

July

August

To

appear

-LSB-

-RSB-

R.F.C.

Walters

Categories

and

Computer

Science

volume

of

Cambridge

Texts

in

Computer

Science

Cambridge

University

Press

-LSB-

-RSB-

Philip

Wadler

and

Stephen

Blott

How

to

make

ad-hoc

polymorphism

less

ad-hoc

In

Proceedings

of

the

th

ACM

Annual

symposium

on

Principles

of

Programming

Languages

Austin

Texas

ACM

ACM

Press

-LSB-

-RSB-

H.T.G.

Weffers

Automated

Tree

Generation

-LRB-

ATG

-RRB-

Gofer

meets

LaTEX

In

preparation

A

man

will

turn

over

half

a

library

to

make

one

book

S.

Johnson

Choose

an

author

as

you

choose

a

friend

W.D.

Roscommon

Essay

on

translated

verse

Daarom

wat

andere

mensen

onderwijzen

Zal

ik

ook

overwegen

en

dan

aan

andere

mensen

onderwijzen

Lao

Tzu

Te-Tao

Ching

BIBLIOGRAPHY

Index

F

H

H-spec

fusion

N

N

fusion

-LRB-

-RRB-

o

F

FA

F

H

fusion

algebraic

types

free

Associativity

case

expression

cases

atomic

base

recursive

class

instance

constructor

default

definition

hierarchy

of

es

member

functions

multiple

parameters

super

type

Computation

rules

for

-LRB-

-RRB-

cons-list

constructor

class

function

operator

function

name

pseudo

type

constructors

Constructors

of

FA

context

datatypes

functor

isomorphic

join-list

least

fixed

point

monad

Monad

Decomposition

monotype

natural

formations

isomorphism

naturality

of

o

of

AE

of

-LSB-

of

swap

operators

basic

naturalities

overloading

polymorphism

ad-hoc

parametric

Post-distributivity

predicate

INDEX

qualified

types

recurrence

relation

referential

transparency

relator

binary

composite

endo

initial

map

pointed

sum

simulates

snoc-list

swap

type

class

class

constraint

coercion

constructor

expressions

signature

synonym

variables

variables

grounded

Unit

virtual

data

structure

witness

to

formation

to

isomorphism

to

naturalities

candidate

might-be

INDEX

Name

Index

Abadi

M.

Abramsky

S.

Ackermans

Ascham

R.

Backhouse

R.C.

-LCB-

Bird

R.

Blott

S.

Cardelli

L.

Cocket

R.

Curien

P.-L.

Davie

A.J.T.

Descartes

Doornbos

H.

Douglas

N.

iii

Fasel

J.H.

Forbes

M.

v

Fukushima

T.

Gijsen

B.

Goguen

J.

Hemingway

E.

Hoare

C.A.R

Hoogendijk

P.

-LCB-

Hudak

P.

Hughes

J.

Hutton

G.

Jensen

T.P.

Jeuring

J.

Johnson

E.

Magic

Johnson

S.

Jones

Mark

P.

-LCB-

-LCB-

Jong

E.

v

Knapen

E.

Lao

Tzu

Leroy

Xavier

Lubbock

J.

Malcolm

G.

Melton

A.

Moor

O.

de

Nipkov

T.

O'Donnel

J.

Peirce

C.

Pitt

D.

Poign?e

A.

Popper

K.

Prehofer

C.

Roscommon

W.D.

Rydeheard

D.E.

Sands

D.

Schr?oder

B.S.W.

Shakespeare

W.

Sheeran

M.

Strachey

Strecker

G.E.

Voermans

T.S.

-LCB-

Wadler

P.

Walters

R.F.C.

Weffers

H.T.G

Woude

J.

van

der

-LCB-

NAME

INDEX

NAME

INDEX

After

you

finish

a

book

you

know

you

're

dead

E.

Hemingway