• Aucun résultat trouvé

Both the speiation of the library and a PolyP implementation are presented

N/A
N/A
Protected

Academic year: 2022

Partager "Both the speiation of the library and a PolyP implementation are presented"

Copied!
190
0
0

Texte intégral

(1)

Patrik Jansson

Department of Computing Siene

Chalmers University of Tehnology and Goteborg University

Goteborg, 2000

(2)
(3)

Funtional Polytypi

Programming

Patrik Jansson

Departmentof Computing Siene

Chalmers University of Tehnology and Goteborg University

Goteborg, Sweden, May 2000

(4)

ISBN91-7197-895-X

Patrik Jansson,2000

Doktorsavhandlingar vid Chalmers Tekniska Hogskola

Ny serie nr 1584

ISSN 0346-718x

Computing Siene

Chalmers University of Tehnology and Goteborg University

SE-412 96Goteborg

Sweden

(5)

Patrik Jansson

Department of ComputingSiene

Chalmers University of Tehnology and Goteborg University

Abstrat

Many algorithmshave to beimplemented overand over again fordierentdata-

types, either beause datatypes hange during the development of programs, or

beause the same algorithm is used for several datatypes. Examples of suh al-

gorithmsare equalitytests, prettyprinters, and patternmathers,and polytypi

programming is a paradigm for expressing suh algorithms. This dissertation

introdues polytypi programmingfor funtionalprogramminglanguages, shows

how toonstrut and prove properties of polytypi algorithms, presents the lan-

guageextensionPolyPforimplementingpolytypialgorithmsinatypesafeway,

and presents a number of appliations of polytypi programming. The applia-

tionsinludealibraryof basipolytypibuildingbloks,PolyLib,andtwolarger

appliations of polytypi programming: rewriting and data onversion.

PolyP extends a funtional language (a subset of Haskell) with a onstrut for

dening polytypi funtions by indution on the struture of user-dened data-

types. Programs inthe extended languageare translated to Haskell.

PolyLib ontains powerful strutured reursion operators like atamorphisms,

maps and traversals, aswell aspolytypi versions of a number of standard fun-

tions from funtional programming: sum, length, zip, (==), (6), et. Both the

speiation of the library and a PolyP implementation are presented.

The rst larger appliation is aframework for polytypi programmingonterms.

WeshowthataninterfaeoffourfuntionsissuÆienttoexpresspolytypifun-

tionsforpatternmathing,uniationandtermrewriting. Usingthisframework,

atermrewritingfuntionisspeiedandtransformedintoaneÆientandorret

implementation.

In the seond appliation, a number of funtions for polytypi data onversion

are implemented and proved orret. The onversions onsidered inlude pretty

printing,parsing,pakingandunpakingofstrutureddata. Theonversionfun-

tionsare expressed inanembeddeddomainspeilanguagefordata onversion

(ahierarhy of Haskell's onstrutor lasses).

Keywords: Programming languages, Funtional programming, Algebraidata-

types, Polytypiprogramming, Generiprogramming

AMS 1991 subjet lassiation68N15, 68N20

(6)

1. Patrik Jansson and Johan Jeuring. A framework for polytypi program-

ming onterms, with anappliation to rewriting. In Workshop on Generi

Programming,2000.

2. Patrik Jansson and Johan Jeuring. Polytypi data onversion programs.

Submitted forpubliation, 2000.

3. P. Jansson and J. Jeuring. Polytypi ompat printing and parsing. In

Doaitse Swierstra, editor, Proeedings of the 8th European Symposium on

Programming, ESOP'99, volume 1576 of LNCS, pages 273{287. Springer-

Verlag, 1999.

4. R. Bakhouse, P. Jansson, J. Jeuring, and L. Meertens. Generiprogram-

ming: Anintrodution. InAdvanedFuntionalProgramming,volume1608

of LNCS, pages 28{115. Springer-Verlag,1999.

5. PatrikJanssonandJohanJeuring. Funtional pearl: Polytypiuniation.

Journal of Funtional Programming, 8(5):527{536,September 1998.

6. P. Jansson and J. Jeuring. PolyLib { a polytypifuntion library. Work-

shop onGeneri Programming,Marstrand, June 1998.

7. PolyP | a polytypi programming language extension. In Conferene

Reord of POPL '97: The 24th ACM SIGPLAN-SIGACT Symposium on

Priniples of Programming Languages,pages 470{482. ACMPress, 1997.

8. J. Jeuring and P. Jansson. Polytypi programming. In J. Launhbury,

E. Meijer, and T. Sheard, editors, Advaned Funtional Programming '96,

volume 1129 of LNCS, pages 68{114. Springer-Verlag,1996.

Available fromthe Polytypi programmingWWW page [49℄.

http://www.s.halmers.se/ ~pat rikj /po ly/

(7)

1 Introdution 1

1.1 What is apolytypifuntion? . . . 2

1.2 Polymorphismand polytypism . . . 3

1.3 Why polytypiprogramming? . . . 4

1.4 Sope . . . 5

1.5 Approahes to writingpolytypiprograms . . . 6

1.6 The PolyP system. . . 7

1.7 Overview. . . 7

2 Prelude 9 2.1 Context . . . 9

2.2 The funtiontype . . . 9

2.3 The disjointsum type . . . 10

2.4 The unit type . . . 11

2.5 The pair type . . . 11

2.6 The Haskell bottom . . . 12

2.7 Booleans, truth values and prediates . . . 13

2.8 Computationsthat may fail . . . 15

2.9 Polymorphilists . . . 16

2.10 Overloadingand lasses . . . 17

2.11 Fixed points . . . 17

2.11.1 Fixed point indution. . . 18

2.11.2 Explainingxed point indution . . . 20

3 Basi polytypi programming 23 3.1 The struture of lists . . . 24

3.2 Catamorphisms and fusionfor lists . . . 26

3.3 The struture of trees . . . 29

3.4 Pattern funtors. . . 31

3.5 In and out of aregular datatype . . . 32

3.6 The polytypionstrut . . . 33

3.7 Catamorphisms and maps . . . 35

3.8 Catamorphisms onspei datatypes . . . 37

(8)

3.9 Separate: asimple PolyP program. . . 38

3.10 Polytypi laws . . . 40

4 PolyP | a polytypi programming language extension 45 4.1 Type inferene. . . 45

4.1.1 The ore language . . . 46

4.1.2 The polytypilanguageextension . . . 47

4.1.3 Uniation. . . 50

4.1.4 Type heking the polytypionstrut. . . 50

4.2 Semantis . . . 52

4.3 Code generation . . . 55

4.4 Implementation . . . 56

4.5 Conlusionsand future work . . . 56

5 PolyLib | a polytypi funtion library 59 5.1 Desribingpolytypifuntions . . . 60

5.1.1 Notationand naming . . . 60

5.1.2 Library overview . . . 60

5.2 Reursion operators . . . 61

5.3 Zips . . . 64

5.4 Monad operations . . . 67

5.5 Flattenfuntions . . . 69

5.6 Misellaneous . . . 70

5.7 Conlusions . . . 71

6 Rewriting 73 6.1 Introdution . . . 73

6.1.1 An examplerewriting system . . . 74

6.1.2 Polytypi rewriting . . . 75

6.2 A term interfae. . . 76

6.2.1 Terms . . . 76

6.2.2 Polytypi Term instanes . . . 78

6.2.3 Combinators onterms . . . 79

6.2.4 Laws for term ombinators . . . 80

6.3 Substitutions,mathing and uniation . . . 82

6.3.1 Substitutions . . . 82

6.3.2 Mathing . . . 83

6.3.3 Uniation. . . 84

6.4 Rewriting . . . 86

6.4.1 One step rewriting . . . 87

6.4.2 Rewritingtonormal form . . . 88

6.4.3 Conrete xed points . . . 90

(9)

6.4.5 EÆieny omparison. . . 95

6.5 Proofs . . . 96

6.5.1 Proofs of term ombinatorlaws . . . 97

6.5.2 Proofs of rewriting transformations . . . 101

6.6 Conlusions . . . 104

7 Polytypi Data Conversion Programs 105 7.1 Introdution . . . 105

7.1.1 Data onversion programs . . . 106

7.1.2 Construtingdata onversion programs . . . 107

7.2 Shape . . . 109

7.2.1 Funtionseparate . . . 109

7.2.2 Funtionombine . . . 110

7.2.3 Funtionombine is the inverse of separate . . . 111

7.3 Arrows and laws . . . 111

7.3.1 Basidenitions and laws for arrows . . . 111

7.3.2 A lass for arrows . . . 114

7.3.3 An inverse lawfor arrow produts . . . 116

7.3.4 Fixed point indution and arrows . . . 117

7.4 Arrowmaps . . . 117

7.4.1 The arrowmaps are inverses . . . 118

7.5 Paking . . . 121

7.5.1 The onstrutionof the paking funtion . . . 123

7.6 Pretty printing . . . 128

7.6.1 More arrowlasses . . . 128

7.6.2 Denition ofpshow and pread . . . 131

7.7 Generating arrow instanes. . . 137

7.7.1 An instane for ArrowReadShow . . . 140

7.8 Results and onlusions. . . 141

8 Related work 145 8.1 BMF = Squiggol . . . 145

8.2 Theories of datatypes . . . 146

8.3 Beyond regulardatatypes . . . 146

8.4 Spei polytypi funtions . . . 147

8.5 Type systems . . . 148

8.6 Implementations . . . 149

8.7 Polytypi transformationsand proofs . . . 149

8.8 ImperativePolytypi Programming . . . 150

Aknowledgments 153

(10)

A An implementation of PolyLib 165

A.1 Struturedreursion operators . . . 165

A.2 Crush . . . 166

A.3 Monadireursion operators . . . 167

A.4 Thread . . . 169

A.5 ThreadFuns . . . 170

A.6 Propagate . . . 171

A.7 Zip . . . 171

A.8 Equal . . . 174

A.9 Compare . . . 175

A.10Flatten . . . 176

A.11Sum . . . 177

A.12CrushFuns . . . 177

A.13ConstrutorName . . . 178

(11)

Introdution

The ability toname and reuse ommonpatterns of omputationas higher-order

funtions is at the heart of the power of funtional languages. Higher-order

funtionslikemapsandatamorphismsaptureverygeneralprogrammingidioms

that are useful in many ontexts. This kindof polymorphi funtionsenables us

to abstrat away from the unimportant details of an algorithmand onentrate

onits essential struture.

The type of a polymorphifuntion has type parameters, but all monomorphi

instanesofthefuntionanuseidentialode. Ageneralizationistoparametrize

alsothefuntiondenitionontypes. Funtionsthat areparametrizedinthisway

arealledpolytypifuntions [61℄. Equalityfuntions,prettyprintersandparsers,

traversal funtionsand otherreursion ombinatorsare allexamplesofpolytypi

funtions.

Whilea normalpolymorphifuntion is analgorithmthat is independent of the

typeparameters,the lass ofinstanes of apolytypifuntionontains funtions

that are dierent, but whih share a ommon struture. Any algorithm in the

lass an be obtained by instantiating a templatealgorithm with (the struture

of) a datatype.

Other terms used for polytypism in the literature are strutural polymorphism

(Ruehr [94℄), type parametri programming (Sheard [97℄), generi programming

(Bird, de Moor and Hoogendijk [7℄), polynomial polymorphism (Jay [55℄), shape

polymorphism (Jay [56℄) and type indexed funtions (Hinze [35℄). A detailed

overview of polytypiprogrammingin relatedwork is presented inChapter 8.

In the sequel we willassume that the readerhas some knowledgeof a funtional

programming language, preferably Haskell [90℄. This hapter explains briey

what polytypi funtions are, why they are useful and how they an be imple-

mented. It alsodesribesthe sope of this dissertation and presents anoverview

of the followinghapters.

(12)

1.1 What is a polytypi funtion?

To give an example of what a polytypi funtion is we show that the denitions

of the funtion sum on dierent datatypes share a ommon struture. The sum

funtion takes a struture ontaining integers and returns the sum of all the

integers in the struture. The normal sum funtion for lists an be dened as

follows in the funtional languageHaskell:

sum ::[Int℄ ! Int

sum [℄ = 0

sum (x :xs) = x +sum xs

We dene sum onthe following datatypes:

data[a℄ = [℄ja:[a℄

dataTree a = Leaf a jBin(Tree a)(Tree a)

dataMaybe a = Nothing jJust a

dataRose a = Fork a [Rose a℄

Weandenethefuntionsumforallofthesedatatypes(instantiatedonintegers)

using atamorphisms. A atamorphism is a funtion that reursively replaes

onstrutorswith funtions. We write ata

D fC

i 7!e

i

g for the atamorphismon

the datatype D a that replaes the onstrutorsC

i

with the expressions e

i .

sum

[℄

:: [Int℄!Int

sum

[℄

= ata

[℄

f[℄7!0;(:)7!(+)g

sum

Tree

:: Tree Int !Int

sum

Tree

= ata

Tree

fLeaf 7!id;Bin 7!(+)g

sum

Maybe

:: Maybe Int !Int

sum

Maybe

= ata

Maybe

fNothing 7!0;Just 7!idg

sum

Rose

:: Rose Int !Int

sum

Rose

= ata

Rose

fFork 7!a l !a+sum

[℄ lg

We an already see some patterns in the parameters of the atamorphism: the

two nullary onstrutors [℄ and Nothing are both replaed by 0 and the two

unary onstrutors Leaf and Just are replaed by the identity funtion id. The

binary onstrutors ((:), Bin and Fork) are replaed by funtions that sum the

subexpressions. Allthedenitionsofsum areinstanesofthefollowingpolytypi

denition of psum:

psum ::Regular d ) d Int !Int

(13)

polytypifsum :: f Int Int !Int

= asef of

g +h ! either fsum fsum

g h ! (x;y)!fsum x +fsum y

Empty ! x !0

Par ! id

Re ! id

dg ! psumÆpmap fsum

Const t ! x !0

Figure1.1: The denition of fsum

Funtion fsum is dened (in Figure 1.1) by indution over the pattern funtor

f that aptures the struture of the regular type onstrutor d. The polytypi

denitionof funtionata and the explanationoffuntion fsum willhavetowait

untilthe polytypionstrut is dened inSetion 3.6.

Higher-order funtions and polytypi funtions an be used together to obtain

even more generaldenitions. Exatlythe samestruture asthat usedforpsum,

an beused to denethe polytypifuntion on,whihonatenates all listsin

astrutureof type d [a℄. We justreplae0by[℄and (+)withlistonatenation

(++) inthe denition of fsum to obtainfon.

on ::Regular d ) d [a℄![a℄

on = ata fon

Both psum and on are polytypi funtions and thusparametrized onthe type

onstrutor d. By abstrating over the operator and its unit, we an generalize

psum (fsum) and on (fon) to the polytypifuntion rush (frush).

rush ::Regular d ) (a !a !a)!a !d a !a

rush op e = ata (frush op e)

where fsum = frush (+) 0 and fon = frush (++)[℄. These funtions, and

many others,are desribed in PolyLib (Chapter 5and Appendix A).

1.2 Polymorphism and polytypism

A parametri polymorphifuntion suh as

(14)

anbeseenasafamilyoffuntions|oneforeahinstaneofaasamonomorphi

type. Parametriityimpliesthathead anmakenoassumptionsaboutthetypea.

Thusall the funtions inthe family are essentiallythe same.

An ad ho polymorphifuntion suh as

(+)::Num a ) a !a !a

is also a family of funtions, one for eah instane in the Num lass. These

instanes may be ompletely unrelated and eah instane is dened separately.

In almostallases, automatitype inferenean be used tond the appropriate

instane for any given ourrene of the (+) operator.

The polymorphismof a polytypi funtion suh as

psum ::Regular d ) d Int !Int

is somewhere in between parametri and ad ho polymorphism. A polytypi

funtion an be seen as a type indexed family of funtions. A single denition

of psum suÆes, but psum has dierentinstanes in dierent ontexts. Here the

ompilergeneratesinstanesfromthedenitionofthepolytypifuntionandthe

typeintheontextwhereitisused. Apolytypifuntionmayalsobeparametri

polymorphi: funtion size ::Regular d ) d a !Int, whih returns the size of

avalue of anarbitrary datatype,is both polytypiand parametri polymorphi.

Meertens [76℄ gives a nie example of the power of parametri polymorphism:

Suppose we wantafuntiontoswaptwointegers: swap ::(Int;Int)!(Int;Int).

Thisisnotaveryhardproblemtosolve,butthereareinnitelymanytypeorret

but wrongsolutions. (Twoare id and (x;y)!(y +1;x).) Ifwegeneralize this

funtiontothe polymorphifuntionswap ::(a;b)!(b;a),then weget amuh

more useful program and we an't make it wrong while type orret. (Stritly

speakingthisistrueonlyinastronglynormalizinglanguage. Ifwehavebottoms,

or non-terminating omputations, as in CPO and in Haskell, then we an still

write a few non-terminating (wrong) versions.) Similarly, even when a funtion

may be needed only for one spei datatype, it may be helpful to dene it

polytypially toredue the risk of making amistake.

1.3 Why polytypi programming?

Polytypiprogramming oersa numberof benets:

Reusability: Polytypism extends the power of polymorphi funtions to allow

(15)

the lass of printing funtions for dierent datatypes an be expressed as

one polytypishow funtion. Thuspolytypifuntionsare verywellsuited

for building programlibraries. PolyLib(Chapter 5) is an example of suh

alibrary.

Adaptivity: Polytypi programs automatially adapt to hanging datatypes.

For example, if we add a onstrutor Node (Tree a) a (Tree a) to the

datatypeTree a,then thesame polytypisum funtionan stillbeused to

sumallintegersinelementsofthe(new)tree type. Thisadaptivityredues

the need for time onsuming and boring rewrites of trivial funtions and

eliminatesthe assoiated riskof making mistakes.

Closure and orthogonality: Currently some polytypi funtions an be used

butnot dened inML (theequality funtion(s))and Haskell(the members

ofthederived lasses). Thisasymmetryanberemovedbyextendingthese

languages with polytypi denitions.

Appliations: Some problems are polytypi by nature: maps and traversals

(Setion 5.4), pretty printing and parsing (Setion 7.6), data ompression

(Setion 7.5), mathing (Setion 6.3.2), uniation (Setion 6.3.3), term

rewriting (Setion 6.4), ...

Provability: More general funtions meansmore general proofs. Ifwe onsider

polytypi proofs, then eah of the earlier benets obtains anadditionalin-

terpretation: weget reusable proofs,adaptiveproofs,less ad ho semantis

of programming languages and new proofs of properties of printing and

parsing (Setion 7.6), paking (Setion 7.5), term rewriting (Setion 6.4)

et.

1.4 Sope

As the title suggests this dissertation is about polytypi programmingfor fun-

tional programming languages. More speially, the programs in this disserta-

tionarewritteninthefuntionalprogramminglanguageHaskell98[90℄extended

with withsupportforpolytypidenitions provided by theauthors languageex-

tension PolyP (Chapter 4).

A polytypi funtion an be applied to values of a large lass of datatypes, but

somerestritions apply. Werequirethat apolytypifuntionisappliedtovalues

ofregular datatypesonly. AdatatypeD aisregularifitisnotmutuallyreursive,

ontainsnofuntion spaes,and ifthe argumentsof thedatatype onstrutoron

the left- and right-hand side in its denition are the same. The olletion of

(16)

[a℄,anddierentkindsoftrees. WeusetheonstrutorlassRegular torepresent

the olletionof regular datatypes.

Polytypifuntionsanbedenedonalargerlassofdatatypes, inludingmulti-

pleparameterdatatypes[58℄, mutually reursivedatatypes[14,35,45℄, datatypes

with funtion spaes [26,78℄and nested datatypes [8,34℄but we willnot disuss

these extensions.

1.5 Approahes to writing polytypi programs

There are various ways to implement polytypi programs in a typed language.

(Polytypiprogramsan beimplementedinuntyped languageslikeLisporCbut

without any (stati) type safety. We only onsider strongly typed languages in

this dissertation.) Threepossibilitiesare:

using auniversal datatype;

using higher-orderpolymorphismand onstrutorlasses;

using aspeial syntati onstrut.

Polytypi funtions an be implemented by dening a universal datatype, on

whih wedene the funtionswe wanttohaveavailablefor largelasses ofdata-

types. Thesepolytypifuntionsan beusedonaspeidatatypeif weprovide

translation funtionstoand from the universal datatype. An advantage ofusing

auniversal datatype forimplementingpolytypifuntionsisthat wedonotneed

a language extension for writing polytypi programs. However, using universal

datatypes has several disadvantages: type information is lost in the translation

phase to the universal datatype, and type errors an our when programs are

run. Furthermore, dierent people will use dierent universal datatypes, whih

willmake programreuse more diÆult.

Ifweusehigher-orderpolymorphismandonstrutorlassesfordeningpolytypi

funtions (as in Jones [65℄), then type informationis preserved, and we an use

a funtional language suh as Haskell for implementing polytypi funtions. In

this style all regulardatatypes are represented by the type

dataMu f a = In (f a (Mu f a))

and the lass system is used tooverload funtions like map and ata. However,

writing suh programs is rather umbersome: programs beome luttered with

instanedelarations,andtypedelarationsbeomelutteredwithontexts. And

(17)

Beause the rst two solutions towriting polytypifuntions are unsatisfatory,

we have extended (a subset of) Haskell with a syntati onstrut for dening

polytypi funtions. We willuse the name PolyP both for the extension and the

resultinglanguage.

1.6 The PolyP system

PolyPisanextensionofafuntionallanguagethat allowsprogrammerstodene

and use polytypi funtions. The underlying language in this dissertation is

a subset of Haskell and hene lazy, but this is not essential for the polytypi

extension. The extension introdues a new kind of (top level) denition, the

polytypi onstrut,used todene funtionsby indution over the struture of

datatypes. Beause datatype denitions an express sum-, produt-, parametri

and reursive types, the polytypi onstrut must handle these ases.

PolyP type heks polytypivalue denitions and, when using polytypi values,

types are automatially inferred. (Just as in Haskell, sometimes expliit type

annotations are needed to resolve overloading.) The type inferene algorithm

is based upon Jones' theories of qualied types [64℄ and higher-order polymor-

phism [66℄. The semantis of PolyP is dened by adding type arguments to

polytypi funtions in a ditionary passing style. We give a type based transla-

tion from PolyP to Haskell that uses partial evaluation to remove all ditionary

values atompile time. Thus we avoid run time overhead for reating instanes

of polytypi funtions.

The ompilerfor PolyP is still under development, and has a number of limita-

tions. Polytypifuntionsanonlybeappliedtovaluesofregulardatatypes. The

underlying subset of Haskell laks many useful onstruts suh as modules and

instane delarations. Extensions to handle multiple type arguments, mutually

reursive datatypes and allof Haskell are planned for the forthomingsuessor

of PolyP: Generi Haskell [33℄.

1.7 Overview

The dissertation ontains an introdution to polytypi programming,a desrip-

tion of the language extension PolyP and its library PolyLib and two larger

polytypi appliations: term rewriting and data onversion.

Chapter 2 is a non-polytypi prelude to the rest of the dissertation. It denes

notation, useful funtions and laws tobe used in the sequel.

Chapter 3is anintrodutiontofuntional polytypiprogramming. Thishapter

(18)

funtions: itdenesatamorphisms,polytypimap funtions,funtionpsumused

in the preeding example and presents the polytypi onstrut whih is used

for dening polytypi funtions by indution over the struture of user-dened

datatypes. This hapter alsopresents some polytypi proof rules and uses these

rules toprove properties about polytypi funtions.

Chapter4brieydesribesthetheoryandimplementationofPolyP:thetypesys-

tem that preserves Haskell-like typeinferene provided the polytypionstrut

isexpliitlytyped, andthesemantisintermsofatranslationofPolyP-programs

into Haskell. The theory from this hapter is not essential for reading the rest

of the dissertation. The hapter is based on the POPL'97 paper PolyP | a

polytypi programming language extension [46℄.

Chapter 5 presents a library of polytypi building bloks that an be used in

appliations. Eah funtion is presented with its type and a brief desription

of what it does and how it is related to other polytypi funtions. The hapter

is a revised version of the paper PolyLib | a polytypi funtion library [51℄.

An implementation of PolyLib in the language extension PolyP is inuded in

Appendix A.

Chapter 6 presents the rst larger polytypi appliation: term rewriting. This

hapter presents aninterfae for polytypiprogramming onterms, and uses this

interfae to desribe polytypi algorithmsfor mathing, uniation and eÆient

termrewritingtogetherwithsomeorretnessproofs. Thehapterisanextended

version of the artile A framework for polytypi programming on terms, with an

appliation to rewriting [52℄.

Chapter7istheseondlargerpolytypiappliation: dataonversion. Itpresents

polytypi funtionsfor maps and traversals, data ompression,and pretty print-

ing. Foreah onversion, a pair ofinverse funtions is onstrutedtogether with

a proof of orretness. The onversion funtions are expressed in an embedded

domainspei languagefor dataonversion. Theembedded languageisdened

asa hierarhy of Haskell's onstrutorlasses, based onHughes' Arrows [42℄.

Chapter8givesanoverviewofpolytypisminrelatedwork. Itdesribestheorigins

ofpolytypism,thedierentapproahesusedtoexpress,typehekandimplement

polytypism and gives many referenes to further readingabout polytypism.

(19)

Prelude

This hapter is for the dissertation what the standard prelude is for Haskell: a

olletionof ommonresoures whih an be used everywhere withoutexpliitly

havingtodenethemloallyorimportthem. Thepreludeisdividedintosetions

thatpresentsome notationand afew basidatatypeswith assoiated operations

and laws.

2.1 Context

For speiations, program ode and proofs, we use Haskell [90℄ notation with

a few typographial enhanements toimprove readability. In a few plaes these

enhanements lash with the formalsyntax for Haskell. For example, we use (;)

forforwardomposition(thatis,f ;g =gÆf)althoughHaskellusesthesemiolon

only as a separator. Where possible, inluded program ode is automatially

pretty printed fromHaskell orPolyP soureode toavoid errors.

In ategorytheory, afuntor is amappingbetween ategories that preserves the

algebraistrutureoftheategory. Beauseaategoryonsistsofobjets(types)

andarrows (funtions),afuntoronsistsoftwoparts: adenitionontypes, and

a denition on funtions. We normally work in the ategory CPO of omplete

partialorders and ontinuous funtions between them.

2.2 The funtion type

The Haskell type ofpartial funtionsfroma tob iswritten a !b anda lambda

expression with patterna and body b is written a !b. The identity funtion,

(20)

onstant funtion and funtionomposition are dened as follows:

id :: a !a

id x = x

onst :: a !b !a

onst k = k

(Æ) :: (b !)!(a !b)!(a !)

(f Æg)x = f (g x)

Funtions of multiple arguments are normally urried in ontrast to languages

like Ada, Java and SML where funtions normally take a tuple of arguments.

The funtions urry and unurry onvert between these twoviews:

urry :: ((a;b)!)!(a !b !)

urry f x y = f (x;y)

unurry :: (a !b !)!((a;b)!)

unurry f p = f (fst p)(snd p)

2.3 The disjoint sum type

The disjoint sum type Either a b in Haskell onsists of left-tagged elements of

typea,andright-taggedelementsoftypeb,andhasonstrutorsLeft andRight,

whih injet elementsinto the left and rightomponent of a sum respetively.

dataEither a b = Left a jRight b

Left ::a !Either a b

Right ::b !Either a b

Funtion l r r (written either l r in Haskell) is a shorthand notation for ase

analysis. Funtion( r ) is the atamorphismon Either. It takes a funtion l of

type a ! and a funtion r of type b ! , and replaes Left with l and Right

with r:

(r )::(a !)!(b !)!(Either a b !)

(l r r)(Left x) = l x

(l r r)(Right y) = r y

The operator ( + ) is used to apply either l or r inside Left or Right. It is a

two-argument mappingfuntion onEither.

( + )::(a !)!(b !d)!(Either a b !Either d)

(l + r)(Left x) = Left (l x)

(21)

The followingfuntionaldenition of ( + ) isequivalent and easier toalulate

with:

l + r = (LeftÆl)r (Right Ær)

Funtion( + ) satises two funtor laws and operator( r ) satises two fusion

laws:

id + id = id

(f + g)Æ(h + i) = (f Æh) + (g Æi)

f Æ(g r h) = (f Æg)r (f Æh)

(f r g)Æ(h + i) = (f Æh) r (g Æi)

2.4 The unit type

The nullaryprodut type and itsonly onstrutor are both writtenas ():

data() = ()

2.5 The pair type

The binary produt type and its elements are written as pairs (a;b). Funtions

fst and snd are the twoprojetions.

data(a;b) = (a;b)

fst (a;b) = a

snd (a;b) = b

The duals of ( r ) and ( + ) are (

) and ( ),respetively.

(

)::(a !b)!(a !)!(a !(b;))

(f

s)x = (f x;s x)

The operator ( ) is the analogueof map on produts.

( )::(a !)!(b !d)!((a;b)!(;d))

(f s)(x;y) = (f x;s y)

By analogy with the denition of ( + ) we have an equivalent funtion level

denition:

(22)

Funtion( )satisestwobifuntorlawsandoperator(

)satisestwofusion

laws:

id id = id

(f g)Æ(h i) = (f Æh) (gÆi)

(f

g)Æh = (f Æh)

(gÆh)

(f g)Æ(h

i) = (f Æh)

(gÆi)

2.6 The Haskell bottom

All Haskell types have a bottom element denoting a non-terminating omputa-

tion and we an dene a polymorphi value ? by the following trivial reursive

denition:

?::a

? = ?

Inontrast tomost theoretialframeworks thefuntion type,the empty and the

binary produt typein Haskell are all lifted:

(x !?) 6= ?::a !b

() 6= ?::()

(?;?) 6= ?::(a;b)

Among other things,this meansthat for Haskell:

-expansionis not semantis preserving: if f = ?::a !b, then

x !f x = x !?x = x !? 6= ? = f :

The type() is not aterminal objet asit has twoelements: ? and ().

Andwe do not have surjetive pairing: if p = ?::(a;b),then

(fst p;snd p) = (fst ?;snd ?) = (?;?) 6= ? = p :

To sum up | almost no laws from CPO hold in Haskell! As this would lead to

onsiderableproblems inthe detailedproofs,werestrit ourselves totheunlifted

versions of these types. As we use Haskell for the implementations this means,

stritly speaking, that most of the results presented in this dissertation are not

proved fortheatualrunningode butforidealizedversions. Thishas notturned

(23)

2.7 Booleans, truth values and prediates

The booleanvalues False and True are the onstrutorsof the type Bool:

dataBool = False jTrue

Notethat the Haskell type Bool ontainsa leastvalue,?, inadditiontothe two

truth values. When we really need only truth values we use the type Truth =

fFalse;Trueg and onvert from Bool to Truth by identifyingFalse and ?:

b::Bool ! Truth

bTrue = True

b = False

The expression bbmeans \the alulationof b terminates with the value True"

and is pronouned\b is true" for short.

Wehavetheommonoperationsimpliation()),and(^),or(_),andnegation

(:) for alulating with Booleans and with Truth values, and if-expressions to

selet between two expressions. We use the same syntax for operations on Bool

and operations onTruth.

We often work with prediates instead of booleans to simplify alulations. We

oftenuse the same syntax for the pointwise liftedoperations.

false;true :: a !Bool

false = onst False

true = onst True

());(^);(_) :: (a !Bool)!(a !Bool)!(a !Bool)

p ) q = x !p x ) q x

p ^ q = x !p x ^ q x

p _ q = x !p x _ q x

i p thent elsee = x !if p x thent x elsee x

b :: (a !Bool)!(a !Truth)

bp = x !bp x

Asanexampleofthe use oftheliftedbooleanoperationsweanspeify pre-and

post-onditionsfor a funtion f:

bpre ) bpostÆf :

Expandingthe denitions of the liftedoperators this is equivalentto:

(24)

Ifthis prediate equals true (that is, for allx the body isTrue),then f satises

itsspeiation.

The Haskell equality test (==)::Eq a ) a !a !Bool isalsolifted:

(===) :: Eq b ) (a !b)!(a !b)!(a !Bool)

f ===g = x !f x ==g x

The liftedversion of the law(f x ==f y) ( (x == y) beomes:

Lemma 2.1 Canel(fÆ):

(f Æg ===f Æh) ( (g ===h)

We willoften reason about funtions that are equal when restrited to a subset

of their domains:

Denition 2.2 Funtion equalityon a subset:

(

===)::Eq a ) (b !Bool)!(b !a)!(b !a)!(b !Truth)

f p

===g = x !bp x ) bf x ==g x

or, equivalently, using the lifted operations:

f p

===g = bp ) bf ===g

We willlater use the following property of ( p

===):

Lemma 2.3 Fator ( p

===):

gÆf pÆf

===h Æf ===(g p

===h)Æf

The liftedversion of b satises the following laws:

Lemma 2.4 Fator out f from b:

bpÆf===bpÆf

Lemma 2.5 Canel(Æf):

bpÆf ( bp

(25)

Simplelaws for booleanslift immediatelytoprediates:

Law 2.6 (exp1): (a _ b) ) (a ) ) ^ (b ) )

Law 2.7 (exp2): a ) (b _ ) (a ) b) _ (a ) ).

Laws fori then else:

Lemma 2.8 i then else-fusion:

For all strit f:

f (i b then pelse q) = i b thenf p elsef q

Lemma 2.9 i p then p

(i p thenbpelse x) = (i p then true elsex)

Lemma 2.10 Expressing (_) using i then else:

bp _ q = i bpthen true elsebq

2.8 Computations that may fail

The datatype Maybe a is used to model omputations that may fail to give a

result.

dataMaybe a = Nothing jJust a

Forexample,wean denetheexpression divide m n tobeequaltoNothing ifn

equals zero, and Just (m =n) otherwise. A funtion that handles values of type

Maybe a onsistsof two omponents: aomponent that dealswith Nothing,and

aomponent that deals with valuesof the formJust x.

maybe ::b !(a !b)!Maybe a !b

maybe n j Nothing = n

maybe n j (Just x) = j x

Funtionmaybe isanexample ofa atamorphism. FuntionmapM takes afun-

tion f, and a value of type Maybe a, and returns Nothing in ase the argument

equals Nothing,and Just (f x) inase the argumentequals Just x.

mapM ::(a !b)!Maybe a !Maybe b

(26)

FuntionmapM satisestwo funtorlawsand funtionmaybe satisestwofusion

laws:

mapM id === id

mapM f ÆmapM g === mapM (f Æg)

f Æmaybe n j === maybe (f n)(f Æj)

maybe n j ÆmapM f === maybe n (j Æf)

It is sometimes useful tohave prediates totest forJust and Nothing:

isJust;isNothing :: Maybe a !Bool

isJust (Just ) = True

isJust Nothing = False

isNothing Nothing = True

isNothing (Just ) = False

2.9 Polymorphi lists

The polymorphi listdatatype inHaskellis written [a℄ and has a onstrutor [℄

for the empty listand aninx (:) for prepending a value to a list. There is also

syntati sugar for lists: for example [1;2;3℄means 1:2:3:[℄.

data[a℄ = [℄ja:[a℄

The syntaxfor the listonstrutorsisa littledierentfromother datatypes. We

willsometimes use adenition more in linewith otheruser-dened datatypes:

dataList a = Nil jCons a (List a)

Youan think about this just asa dierent syntax for the built-in lists.

The Haskell funtion foldr ()e is a atamorphismfor lists |it replaes uses

of the onstrutor (:)with () and uses of [℄ with e:

foldr ()e [℄ = e

foldr ()e (a:as) = afoldr ()e as

Funtionmap f maps the funtion f overall elementsin alist:

(27)

Funtion map satises two funtor laws and funtion foldr satises two fusion

laws: (h is strit)

map id === id

map f Æmap g === map (f Æg)

hÆfoldr f e === foldr g (h e) ( 8x y: h (f x y)==g x (h y)

foldr f eÆmap g === foldr (f Æg)e

Forreferene we present a fewother listfuntions here as well:

null :: [a℄!Bool

null [℄ = True

null ( : ) = False

nil :: b ![a℄

nil x = [℄

singleton :: a ![a℄

singleton x = [x℄

(++) :: [a℄![a℄![a℄

xs++ys = foldr (:)ys xs

2.10 Overloading and lasses

WewilloftenuseHaskell'slasssystem[66℄towritegenerioverloadedode. This

isvisibleintypesasontext)normaltype whereontextliststhelassonstraints

thevariablesinnormaltypemustsatisfy. Anexampleissort ::Ord a)[a℄![a℄

wherea is restrited tobein the lass Ord of types with aomparison operator.

We use the Haskell lass Monad for monadiomputations [102℄.

lassMonad m where

return :: a !m a

(>>=) :: m a !(a !m b)!m b

(>>) :: m a !m b !m b

fail :: String !m a

2.11 Fixed points

For alulations and proofs involving reursively dened values, we oftenuse an

(28)

in support for reursive denitions over all types and we an diretly dene a

xed pointombinatorx:

x ::(a !a)!a

x f = f (x f)

We all f an improvement funtion | it takes an approximation of the xed

point toa better approximation.

2.11.1 Fixed point indution

Theorem 2.11 Fixed point fusion:

f Æg = hÆf ) f (x g)==x h

The requirement of the xed point fusion law is often too strong | a weaker

requirement an be obtained by observing that the equality is only needed for a

hain of nite approximations of g:

8i: f (g a

i

) = h (f a

i

)where a

i

= g i

?

This in turnan be expressed indutively:

P (?) ^ 8x: P (x) ) P (g x)

where P (x) = f (g x)==h (f x)

The rolling rule [84℄ is asimple appliation of xed point fusion:

Lemma 2.12 The rolling rule: for all funtions f ::a !b and g ::b !a

x (f Æg)===f (x (g Æf))

In the sequel we will use a powerful xed point law that relates n xed points.

Fortheformulationof thexed pointlawwe needtointroduethe onept ofan

inlusive relation as dened in Shmidt [95℄ (other names used in the literature

are \admissible" and \limitlosed").

Denition 2.13 A relationP is inlusive i for all hains of tuples (a i

1

;:::;a i

n )

(8i: P (a i

1

;:::;a i

n

)) ) P ( G

a i

1

;:::;

G

a i

n )

(29)

Inlusiverelationsareusedtoprovepropertiesaboutxed pointsfromproperties

of nite approximations of these xed points. The expression F

i a

i

denotes the

leastupper bound ofthe hain a

i

with respet totheapproximationordering(v)

of the CPO. Tuples are ordered pointwise. A useful soure of inlusive relations

is the following theorem.

Theorem 2.14 A lass of inlusive relations: [95, def. 6.28℄

A relation P isinlusive if P (f

1

;:::;f

n

) has the form:

8d

1 2D

1

;:::;d

m 2D

m :

k

^

i=1 (

l

_

j=1 Q

ij )

where Q

ij

an be either

1. A prediate using only the d

i

as free identiers.

2. An inlusion e

1 v e

2

where e

1

and e

2

are expressions using ontinuous

funtions and only the f

i

and the d

i

as free identiers.

A funtion is ontinuous if it is monotone with respet to the (v) ordering and

if itpreserves leastupperbounds. Allonstrutionsinafuntionallanguagelike

Haskell are ontinuous, but some operators in the semantidomain are not. On

Truth, the operators (^) and (_) are ontinuous but negation (:) is not even

monotone and asa ) b = :a _ b, neitheris ()).

Twoexamples of inlusiverelations are

r

1

:: Bool !Truth

r

1

(b) = bb

r

2

:: (Truth;Truth)!Truth

r

2

(a;b) = a ) b

Proof: Funtionsr

1 andr

2

areinlusive,beauseweanrewritetheirdenitions

tomath the formof Theorem 2.14:

r

1

(b) = bb = (b vTrue) ^ (True vb)

r

2

(a;b) = a ) b = a vb :

(30)

Theorem 2.15 Fixed point indution: [95, def. 6.26℄

For every inlusive relation P, and for allimprovement funtions i

1

;:::;i

n :

(P (?;::: ;?) ^ 8f

1 :::f

n : P (f

1

;:::;f

n

) ) P (i

1 f

1

;:::;i

n f

n ))

)P (x i

1

;:::;x i

n )

A typialexample appliationof this theorem isfound inprovingthat two fun-

tions g = x ig and h = x ih are equal on the set where a prediate

p = x ip holds. Note that the prediate is also dened as a xed point.

We use xed point indution with n = 3, the relation P (x;y;z) = x z

===y

and improvementfuntions ig, ih and ip.

Thebaseaseiseasy: theprediate?isnevertrue,andallfuntionsaretrivially

equalon the empty set, sowhat is left isthe following:

Theorem 2.16 x-equality:

(8x y z: x z

===y ) ig x ipz

===ih y) ) x ig xip

===x ih

2.11.2 Explaining xed point indution

Toproveapropertyofaxedpointdenitionusingxed pointindutionwehave

to identify a relation that implies the desired property if instantiated with the

xed points, and whih holds for all approximations of the xed point as well.

Theproofofsuhapropertyissimilartoaproofbynormalindutionandonsists

of a series of steps. We formulate a relation P

0

to be proved, we prove the base

aseand westartworkingonthe indutivease untilweneedapropertythatwe

annot prove without some side ondition. Assuming that the original theorem

is true (and provable) it should be possible toprove the side ondition together

with P

0

. Sothen we formulate a relationP

1

that implies the side ondition, and

strengthen the indutive hypothesis to P = P

0

^ P

1

. This means extra work

inproving a new base ase and indutive ase for P

1

, but on the other hand the

indutive ase for P

0

makesa goodleap forward. We repeat this proedure until

we have an indutive proof of P = P

0

^ ::: ^ P

n

| this trivially implies P

0

and we are done.

If,morespeially,wewanttoprovethatafuntionhasaertainpropertywhen

restrited toapartiularset, whereboththe funtionsand the set are dened as

xed points,thenthenew relationstoprove areoftwokinds|thoserelatingall

the parametersand those restriting onlythe set. Anexample (overed in detail

in Chapter 6) is proving that a rewriting funtion always produes a term in

normalformwhenrestritedtothe setofnormalizingterms. Asweareinterested

(31)

denitions, the set-only properties an be proven separately and reused for all

the proofs. This an beviewed asspeializingthe xed point indutionpriniple

to an equality over a spei set, or rather speializing the indutive step to a

known set improvementfuntion i.

A veryuseful set-only property is

InLim ::((a !Bool)!(a !Bool))!(a !Bool)!(a !Truth)

InLim

i

p = bp ) bx i

This restrits the sets we need to onsider to subsets of the xed point (for ex-

amplenite terms,ornormalizing terms). Without this restritionthe indutive

step has to be proven for an arbitrary p and that is often hard. Fortunately,

InLim itself iseasy to prove indutively:

Lemma 2.17 InLim:

If i ::(a ! Bool)! (a !Bool) is an improvement funtion for prediates that

is monotone in the following sense:

8p;q: (bp ) bq) ) (bi p ) bi q)

then InLim

i

an be used as a xed point indution side ondition:

InLim

i

? ^ (8p: InLim

i

p ) InLim

i (i p))

Base ase: InLim

i

? = b? ) bx i = true.

Indutive ase: Byalulation:

InLim

i p

fDenition of InLimg

bp ) bx i

) fMonotoniityof ig

bi p ) bi (x i)

fDenition of x: x i = i (x i)g

bi p ) bx i

fDenition of InLimg

InLim

i (i p)

(32)
(33)

Basi polytypi programming

The essene of funtional polytypiprogrammingis thatfuntions an be dened

by indution on the struture of datatypes. The struture of a datatype is de-

sribed by means of a pattern funtor that aptures the top level struture of

elements of the datatype. Just as in imperative languages where it is preferable

tousestruturediterationonstrutssuhaswhile-loopsandfor-loopsinsteadof

unstruturedgotos,itisoftenadvantageoustousestruturedreursionoperators

instead of unrestrited reursion when using a funtional language. Strutured

programs are easier toreason about and more amenable to(possibly automati)

optimizations than their unstrutured ounterparts. Two very useful strutured

reursion operators are the atamorphism operator ata and the polytypimap-

ping funtion pmap. This hapter denes not only ata and pmap, but also a

onstrut with whihit ispossible todenenew reursion operators,tailoredfor

spei needs. (Examples of suh operators are the monaditraversal funtions

inChapter 5and the arrow maps and data onversion programs inChapter 7.)

Thishapterisorganizedasfollows: Setions 3.1{3.3explainthe strutureoftwo

example datatypes (lists and binary trees) in terms of pattern funtors. These

setions also introdue atamorphisms, maps and fusion laws for the example

datatypes, anduse fusiontoproveafew laws inaalulationalstyle. Setion3.4

denes regulardatatypesandshowshowpatternfuntorsareusedtoapturethe

struture ofregulardatatypes. Setion3.5denes the isomorphismsinn andout

thatonvert valuesbetweenaregulardatatypeandthetoplevelstrutureofthat

datatype. Setion 3.6 introdues the polytypi onstrut to express polytypi

funtions by indution over pattern funtors. The denition of the polytypi

sum funtion psum from the introdution is used as an example. Setion 3.7

denes polytypi atamorphisms and maps and Setion 3.8 explains how use

a atamorphism as an evaluator for a small expression language. Setion 3.9

presents a self-ontained polytypi program, together with the ode that the

PolyP generates for that program. Finally, Setion 3.10 states and proves some

polytypi funtion laws.

(34)

3.1 The struture of lists

Consider the datatype List a that is dened by

dataList a = Nil jCons a (List a):

This datatype an be viewed asthe xed point with respet tothe seondargu-

mentof the datatype FList a r dened by

dataFList a r = FNil jFCons a r :

The datatype FList a r desribes the struture of the datatype List a. Note

that FList has one argument more than List. The extra argument is used to

represent the reursive ourrene of the datatype List a in the right-hand side

of its denition. Beause we are only interested in the struture of List a, the

names ofthe onstrutorsof FList are not important. As an elementof FList is

either a nullary onstrutor or a binary onstrutor with its two arguments, we

an instead represent the type FList by:

type FList a r = Either ()(a;r)

WeallFList apatternfuntor asitapturesthereursionpatternofadatatype.

Wenowabstrat fromtheargumentsa andr toobtainavariablefreedesription

of FList. We represent the rst argument by the pattern funtor Par and the

seond argument by Re.

type Par a r = a

type Re a r = r

The type onstrutors in FList are lifted to work on pattern funtors: Either is

lifted to +, the pair type onstrutor ( ; ) is lifted to and the unit type () is

liftedto Empty.

type (f +g)a r = Either (f a r)(g a r)

type (f g)a r = (f a r;g a r)

type Empty a r = ()

As usual, binds stronger than +. Using these pattern funtor onstrutors we

an express FList ina variable freeform.

(35)

The initial objet in the ategory of FList a-algebras (that is, the xed point

of FList with respet to its seond omponent) models the datatype List a.

The initialobjet onsists of two parts: the datatype List a, and a single strit

onstrutor funtioninn

List

, that ombines the onstrutors Nil and Cons.

inn

List

::FList a (List a)!List a

inn

List

= onst Nil r unurry Cons

As anexample, the listontainingonly the integer 3,Cons 3Nil, is represented

by inn

List

(Right (3;inn

List

(Left ()))). Funtionout

List

is the inverse of funtion

inn

List .

out

List

::List a ! FList a (List a)

out

List

Nil = Left ()

out

List

(Cons a b) = Right (a;b)

In the polytypi programming system PolyP these funtions are automatially

suppliedby the system for eahuser-dened datatype.

The pattern funtor FList takes two types and returns a type. FList is a bi-

funtor, whih is witnessed by the existene of a orresponding ation, alled

fmap2

FList

, on funtions. Funtion fmap2

FList

takes two funtions and returns a

funtion.

fmap2

FList

::(a !)!(b !d)! (FList a b !FList d)

fmap2

FList

p r = id + p r

Thatfmap2

FList

isindeedabifuntorfollowsimmediatelyfromtheorresponding

laws for( + )and ( ).

fmap2

FList

id id === id

fmap2

FList

f gÆfmap2

FList

h i === fmap2

FList

(f Æh)(gÆi)

Asanexampleofaprogramwrittenusingtheombinatorsdenedsofarweshow

map

List

f xs that applies funtion f toall elementsof the listxs:

map

List

:: (a !b)!(List a !List b)

map

List

f = inn

List

Æfmap2

FList

f (map

List

f)Æout

List

Funtion map

List

is really the same funtion as map in Haskell but we dene it

dierently here to allowfor a simplegeneralization tothe polytypiase.

Just asFList and fmap2

FList

formafuntor,sodoList andthe funtionmap

List :

map

List

id === id

map f Æmap g === map (f Æg)

(36)

3.2 Catamorphisms and fusion for lists

Funtion size

List

returns the number of elements in a List a (orresponding to

thefuntionlength inHaskell). Theresultofapplyingsize

List

toanargumentlist

an be omputed by replaing uses of the onstrutor Nil by 0, and uses of the

onstrutor Cons by 1+.

Cons 17 (Cons 3 (Cons 8 Nil ))

1+ (1+ (1+ 0 ))

Thusthesizeofthislistis3. Weuseahigher-orderfuntiontodesribefuntions

that replaeonstrutors by funtions: the atamorphism. The atamorphismis

abasistruturedreursionoperatorandonlistsitisequivalenttofuntionfoldr

inHaskell:

foldr f e = ata

List

where ::FList a b !b

= onst e r unurry f

The atamorphismata

List

replaes Nil by e, and Cons by f.

Cons 17 (Cons 3 (Cons 8 Nil ))

f 17 (f 3 (f 8 e ))

Funtionata

List

isdened usingfuntion out

List

to avoidadenition by pattern

mathing. Funtionfmap2

FList

id (ata

List

f) applies ata

List

f reursively to the

rest of the list.

ata

List

::(FList a b !b)!List a !b

ata

List

f = f Æfmap2

FList

id (ata

List

f)Æout

List

The theoretialjustiationfor this denition isthat inthe ategory of FList a-

algebrastheFList a-algebra(List a;inn

List

)isaninitialobjet. Thismeansthat

thereisauniquearrowfrom(List a;inn

List

)toeveryFList a-algebra(b;f). This

unique arrow is the funtion ata

List

f. The initiality of this algebra alsomeans

that ata

List inn

List

is the identity funtionon List a.

Asexamplesweuse funtionata

List

todenethe funtionsize

List

(orresponding

tolength ::[a℄!Int inHaskell) and listonatenation (++).

size

List

:: List a !Int

size

List

= ata

List

(onst 0 r in)

wherein ( ;n) = 1+n

(++) :: List a !List a !List a

xs++ys = ata (onst ys r unurry Cons)xs

(37)

Funtionata

List

satisestheso-alledfusionlaw. Thefusionlawgivesonditions

underwhihintermediatevaluesproduedbyaatamorphisman beeliminated.

Law 3.1 List-fusion: for strit h,

hÆata

List

f = ata

List

g ( hÆf = g Æfmap2

FList id h :

UsingList-fusion wean prove alemma relatingsize

List

and (++).

Lemma 3.2 The size

List

-(++)-lemma:

size

List

(xs ++ys) = size

List

xs +size

List ys :

Proof: In the alulations we abbreviate size

List

with #.

#(xs ++ys) = #xs +#ys

( fAbstrat fromxs g

#Æ(++ys) = (+(#ys))Æ#

( fAssume both sides an be writtenas a atamorphismg

#Æ(++ys) = ata

List

(n r ) = (+(#ys))Æ#

( fTwo subalulationsusing List-fusiong

True

In the rst subalulation we fuse #with (++ys).

# Æ(++ys) = ata

List

(n r )

fDenition of (++ys)g

# Æata

List

(onst ys r unurry Cons) = ata

List

(n r )

( fFusiong

# Æ(onst ys r unurry Cons) = (n r )Æfmap2

FList id#

fDenition of fmap2

FList g

(38)

fLaws for (r )g

(# Æonst ys) r (# Æunurry Cons) = n r (Æ(id #))

fSplit the ( r )sand simplifyg

# Æonst ys = n ^ # Æunurry Cons = Æ(id #)

fIntrodue arguments: ()and (x;n)g

#ys = n () ^ #(Cons x xs) = (x;#xs)

fLet n = onst (#ys)g

True ^ 1+ #xs = (x; #xs)

fLet = ing

True

In the seond subalulation welet m = #ys and we fuse(+m) with #.

(+m)Æ # = ata

List

(n r in)

fDenition of #g

(+m)Æata

List

(onst 0r in) = ata

List

(n r in)

fFusiong

(+m)Æ(onst 0 r in) = (n r in)Æfmap2

FList

id (+m)

fDenition of fmap2

FList g

(+m)Æ(onst 0 r in) = (n r in)Æ(id + (id (+m)))

fLaws for (r )g

((+m)Æonst 0) r ((+m)Æin) = n r (inÆ(id (+m)))

fSplit the ( r )sand simplifyg

(+m)Æonst 0 = n ^ (+m)Æin = inÆ(id (+m))

fIntrodue arguments: ()and (x;n)g

m = n () ^ (in (x;n))+m = in (x;n+m)

fDenitions of n and ing

m = m ^ 1+n+m = 1+n +m

fTriviallyg

True

(39)

3.3 The struture of trees

The datatype Tree a is dened by

dataTree a = Leaf a jBin (Tree a)(Tree a)

Applying the sameproedure as forthe datatypeList a,we obtainthe following

funtor that desribes the struture of the datatype Tree a.

FTree = Par +ReRe

Funtions inn

Tree

andout

Tree

are dened inthe samewayasfuntionsinn

List and

out

List .

inn

Tree

::FTree a (Tree a)!Tree a

inn

Tree

= Leaf r unurry Bin

out

Tree

::Tree a ! FTree a (Tree a)

out

Tree

(Leaf a) = Left a

out

Tree

(Bin a b) = Right (a;b)

Thefuntionsmap

Tree

andata

Tree

aredenedintermsoffuntionsinn

Tree ,out

Tree

and fmap2

FTree :

fmap2

FTree

::(a !)!(b !d)!(FTree a b !FTree d)

fmap2

FTree

p r = p + r r

map

Tree

::(a !b)!(Tree a !Tree b)

map

Tree

f = inn

Tree

Æfmap2

FTree

f (map

Tree

f)Æout

Tree

ata

Tree

::(FTree a b !b)!(Tree a !b)

ata

Tree

f = f Æfmap2

FTree

id (ata

Tree

f)Æout

Tree

Note that the denitions of map

Tree

and ata

Tree

are almost idential to the def-

initions map

List

and ata

List

, only the indies are dierent. Funtion size

Tree is

dened by

size

Tree

:: Tree a !Int

size

Tree

= ata

Tree

(onst 1 r unurry (+))

Thefuntion atten

Tree

,whihreturnsalistontainingthe elementsof theargu-

menttree, an also be dened using funtion ata

Tree :

atten

Tree

:: Tree a ![a℄

atten

Tree

= ata

Tree

(singleton r unurry (++))

(40)

The fusionlawfor trees looks the same as the fusionlawfor lists:

Law 3.3 Tree-fusion: for strit h,

hÆata

Tree

f = ata

Tree

g ( hÆf = gÆfmap2

FTree id h :

We an use this law toprovethat size

List

Æatten

Tree

= size

Tree .

# Æatten

Tree

= size

Tree

fBy denition, introduingthe abbreviations and g

# Æata

Tree

= ata

Tree

( fFusiong

# Æ = Æ(fmap2

FTree id #)

fBy denition of fmap2

FTree g

# Æ = Æ(id + (# #))

fNew abbreviations: =

1 r

2

and =

1 r

2 g

# Æ(

1 r

2

) = (

1 r

2

)Æ(id + (# #))

fLaws for (r )g

(# Æ

1

) r (# Æ

2

) = (

1

Æid)r (

2

Æ(# #))

fSplit the ( r )sand simplifyg

# Æ

1

=

1

^ # Æ

2

=

2

Æ(# #)

fIntrodue arguments,impliitly 8-quantiedg

#(

1

x) =

1

x ^ #(

2 (l;l

0

)) =

2

(#l; #l 0

)

fDenition of

i

and

i g

#[x℄ = 1 ^ #(l ++l 0

) = #l + #l 0

fLemma 3.2g

True ^ True

(41)

3.4 Pattern funtors

A pattern funtor aptures the (top level) struture of a datatype. We repre-

sent a pattern funtor in a variable free form by means of a number of funtor

onstrutors. We have already introdued Par for the datatype parameter, Re

for the reursive parameter, Empty for the empty produt and (+) and () for

lifted versions of Either and (;) and we have used them to dene the pattern

funtorsforlistsand trees. In general,PolyP'spatternfuntorsaregenerated by

the followinggrammar:

f;g;h ::= g +h jg h jEmpty jPar jRe jdg jConst t

where d generates regular datatype onstrutors, and t generates monomorphi

types. Wenote the following about the funtor onstrutors:

The pattern funtor for a datatype with more than two onstrutors is

represented by a nested binary sum assoiating tothe right. Therefore, in

theonrete syntax,theonstrutor+isright-assoiative,sothatf +g+h

meansf +(g+h). Construtor+mayonlyour attop level,sof (g+h)

isanillegalfuntor. Thisrestritionorrespondstothesyntatirestrition

inHaskellwhihsaysthatthevertialbarjthatseparatesonstrutorsmay

onlyour atthe top level of datatypedenitions.

Construtor is right-assoiativeand binds stronger than +.

The onstrutor Empty isthe empty or nullaryprodut.

Composition of funtors d and g is denoted by dg and is only dened

for aunary funtor d and abinary funtor g. Funtoromposition isused

to desribe the struture of types that are dened in terms of other user-

dened datatypes, suhas the datatype of rose-trees:

dataRose a = Fork a (List (Rose a))

--FRose = Par (ListRe)

ThepatternfuntorConst t denotesaonstantpatternfuntorwithvaluet.

The t stands for a monotype suh as Bool, Char or (Int;[Float℄). This

is used when a datatype denition mentions a type other than the type

parameteranddatatypeitself. Anexampleisthe strutureof thefollowing

simple datatype of types:

dataType a = Con String jVar a jFun (Type a)(Type a)

--FType = Const String +Par +ReRe

(42)

List

= FList = Empty +Par Re

Tree

= FTree = Par +ReRe

Rose

= FRose = Par (ListRe)

Type

= FType = Const String +Par +ReRe

Figure 3.1: Examples of patternfuntors.

The type ontextBifuntor f ) isused toindiatethat f isapatternfuntor.

Every regular reursive datatype d a in Haskell is impliitly dened as a xed

point of a pattern funtor

d

a, that is d a

= (

d

a). PolyP provides a type

onstrutor FuntorOf d (we use

d

as a shorthand) for this pattern funtor.

Pattern funtors for the types dened in this hapter are summarized in Fig-

ure 3.1. A datatype d a is regular(satisesRegular d)if itontains no funtion

spaes, and if the argument of the type onstrutor d is the same on the left-

and right-handside of itsdenition. Foreah regulardatatype d a,PolyPauto-

matially generates

d

using roughly the same steps as those used manuallyfor

FList and FTree in previous setions. Pattern funtors are only onstruted for

datatypes dened by means of the dataonstrut. If,somewhere ina program,

apolytypifuntionisappliedtoavalueof typeMaybe (List a),then PolyPwill

generate an instane of the polytypi funtion on the datatype Maybe b (with

b = List a), not onthe type (MaybeList)a.

Aregulardatatypeisdened asthexed pointofapatternfuntor. Thepattern

funtor

d

may, in turn, referto other (previously dened) regular datatypes in

the dg ase. Thus the desriptions of regular datatypes and pattern funtors

are mutually reursive. In pratie, this means that most polytypi denitions

are given as two mutually reursive bindings | one for the datatype level and

one forthepatternfuntorlevel. Similarly,laws forpolytypifuntionsare often

proved bymutualindutionoverthe grammarsforregulardatatypesandpattern

funtors. This indution is well-founded as we don't allow mutually reursive

datatypesand thusadatatypeanonlyrefertoadatatypethatisdened earlier.

In the rest of the paper we always assume that d a is a regular datatype and

that f is a pattern funtor, and we often omit the ontexts (Regular d )

or Bifuntor f ) ) from the types for brevity. This is purely a notational

onvention in the dissertation, expliit types in atual PolyP programs must

ontain the properontext.

3.5 In and out of a regular datatype

In the denition of a funtion that works for an arbitrary (as yet unknown)

(43)

against values. Instead, we use two built-in funtions, inn and out, to onstrut

and destrut a value of an arbitrary datatype from and to its top level om-

ponents. Funtions inn and out are the fold and unfold isomorphisms showing

d a

=

d

a (d a).

inn ::Regular d )

d

a (d a)!d a

out ::Regular d ) d a !

d

a (d a)

Theorem 3.4 Funtions inn and out are inverses.

For every Regular datatype d a:

innÆout ===id ::d a !d a

out Æinn ===id ::

d

a b !

d a b

Note that funtions inn and out are only dened for Regular datatypes d a.

PolyPautomatiallygenerates instanes ofinn and out forallregulardatatypes.

Example instanes were given in Setions 3.1 and 3.3.

3.6 The polytypi onstrut

PolyP introdues anew onstrut polytypifor dening polytypifuntions by

indution overpattern funtors:

polytypip ::[Bifuntor f )℄t = [x

1 :::x

n

!℄asef of ff

i

!e

i g

Here p is the name of the value being dened, t is its type, f is a funtor vari-

able, f

i

are funtor patterns and e

i

are PolyP expressions. The optional funtion

abstration x

1 :::x

n

! is syntati sugar for a polytypi denition with this

abstration in eah of the branhes e

i

. The expliit type in the polytypion-

strut is needed beause we annot in general infer the type from the ases. As

the ase analysis is over pattern funtors, f must be restrited by the ontext

Bifuntor f ),but it is optionalinthe syntax.

The informal meaning is that we dene a funtion that takes (a representation

of) a pattern funtor as its rst argument. This funtion selets the expression

in the rst branh of the ase mathing the funtor, and the expression may in

turnuse thepolytypifuntion(onsubfuntors). Thusthepolytypionstrut is

a(reursive) templatefor onstrutinginstanes of polytypifuntions given the

pattern funtor of a datatype. The funtor argument of the polytypi funtion

neednot(andannot)besuppliedexpliitlybutisinsertedbytheompilerduring

(44)

psum ::Regular d ) d Int !Int

psum = ata fsum

polytypifsum :: f Int Int !Int

= asef of

g +h ! fsum r fsum

g h ! (x;y)!fsum x +fsum y

Empty ! x !0

Par ! id

Re ! id

dg ! psumÆpmap fsum

Const t ! x !0

Figure 3.2: The denition of psum

Asanexamplewetakethepolytypisumfuntiondisussed alreadyintheintro-

dution. Funtion psum (dened inFigure 3.2) sums the integers in a struture

with integers. The denitions of ata and pmap are given later in Setion 3.7.

When psum is used on an element of type Tree Int, the ompiler produes the

ode in Figure3.3for psum

Tree

and fsum

FTree

. Together with the ode generated

psum

Tree

:: Tree Int !Int

psum

Tree

= ata

Tree fsum

FTree

fsum

FTree

:: Either Int (Int;Int)!Int

fsum

FTree

= fsum

Par

r fsum

ReRe

fsum

Par

:: Int !Int

fsum

Par

= id

fsum

ReRe

:: (Int;Int)!Int

fsum

ReRe

= (x;y)!fsum

Re

x +fsum

Re y

fsum

Re

:: Int !Int

fsum

Re

= id

Figure3.3: GeneratedHaskell ode for psum

Tree

and fsum

FTree

for ata

Tree

(presented later in Figure 3.5), this is a omplete denition of the

instane psum

Tree

. Funtion fsum

ReRe

an be rewritten as unurry (+) and,

(45)

summinga tree:

psum

Tree

::Tree Int !Int

psum

Tree

= ata

Tree

(id r unurry (+))

Asexpeted,psum

Tree

isaTree-atamorphismthatreplaes theonstrutorLeaf

with id and the onstrutor Bin with (+).

3.7 Catamorphisms and maps

Thissetiondenes the funtionsata andpmap thatwere used inthedenition

of funtion psum inFigure 3.2.

The atamorphism, or generalized fold, on a datatype takes as many funtions

as the datatype has onstrutors (ombined into a single argument by means of

funtion(r )),andreursivelyreplaes onstrutorfuntionswithorresponding

argument funtions. It is a generalization to arbitrary regular datatypes of the

funtionfoldr that isdened onlists. In spiteof itsgenerality,funtionata an

be dened in just one line in terms of the funtor map, fmap2 (dened later in

Figure3.4):

ata ::Regular d ) (

d

a b !b)!(d a !b)

ata f = f Æfmap2 id (ata f)Æout

Funtion out makes the top level struture of the input expliit, fmap2 applies

(ata f) reursively to the immediate substrutures, and f ombines the results

ofthe reursive allsintothe nalresult. Exeptfor theindies,the denitionof

the polytypi ata is the same as the instanes onList a and Tree a. Similarly,

we an dene apolytypiversion of map:

pmap ::Regular d ) (a !b)!(d a !d b)

pmap p = innÆfmap2 p (pmap p)Æout

Funtion pmap p applies funtion p toall elements of type a in a value of type

d a. Funtionout takes the argumentapart, fmap2 appliesf toparameters and

(pmap f)reursivelytosubstruturesandinn putsthepartsbaktogetheragain.

We all it pmap to avoid a name lash with the normal Haskell funtion map.

The typesof ata and pmap are best explainedby ommuting diagrams:

d a

out

-

d

a (d a)

b ata f

?

d a b fmap2 id (ata f)

?

d a

out

-

d

a (d a)

d b pmapf

?

d

b (d b) fmap2 f (pmap f)

?

(46)

As explained in the prelude, a funtor is a mapping between ategories that

preservesthealgebraistrutureoftheategory. Asaategoryonsistsofobjets

(types) and arrows (funtions), a funtor onsists of two parts: a denition on

types, and a denition on funtions. A pattern funtor in PolyP is a funtion

that takes twotypes and returns a type. The part of the funtor that takes two

funtions and returnsa funtion isalled fmap2,see Figure3.4.

polytypifmap2::(a !)!(b !d)!(f a b !f d)

= p r !asef of

g+h ! fmap2p r + fmap2 p r

gh ! fmap2p r fmap2p r

Empty ! id

Par ! p

Re ! r

dg ! pmap (fmap2p r)

Const t ! id

Figure3.4: The denition of fmap2.

Funtionfmap2

g

isthe funtionationof thepatternfuntorg,andwean show

that pmap

d

isthe funtionationof the typeonstrutor d,viewed asafuntor.

As an example of an instane, Figure 3.5presents the ode generated by PolyP

for ata

Tree

. Funtion out

Tree

was dened in Setion3.3.

ata

Tree

:: (Either a (b;b)! b)!Tree a !b

ata

Tree

i = i Æfmap2

FTree

id (ata

Tree

i)Æout

Tree

fmap2

FTree

:: (a !b)!( !d)! Either a (;)!Either b (d;d)

fmap2

FTree

= p r !fmap2

Par

p r + fmap2

Re Re p r

fmap2

Par

:: (a !b)!( !d)! a !b

fmap2

Par

= p r !p

fmap2

ReRe

:: (a !b)!( !d)! (;)!(d;d)

fmap2

ReRe

= p r !fmap2

Re

p r fmap2

Re p r

fmap2

Re

:: (a !b)!( !d)! !d

fmap2

Re

= p r !r

Figure 3.5: Generated ode for ata

Tree

and fmap2

FTree

Funtionfmap2 andfuntionpmap aremutuallyreursivethroughthedg ase.

Références

Documents relatifs

Spoon provides a unique blend of features: a Java metamodel dedicated to analysis and transformation; a powerful intercession API; static checking of transformations using

A carefully chosen representation of channel types allows us to express (encoded) session type duality solely in terms of type equality and generic types (Section 3).. We equip

For this analysis, 4 different parts of polyp tissues (the tentacle, mouth including pharynx, gonad, and mesenterial filament) were microscopically isolated, and the expression

descriptive data (enrichment of the knowledge of the network) including the actors of these transactions to find typically abnormal behavior. From the point of view of its principle,

resolved with their help to generate an appropriate verbal vehicle. The main body of the thesis relates this attempt and accounts for its failure. The Thesis,

The parallel logic programming languages [9] which were developed a decade ago lie uncomfortably between the categories of ecient implementation languages and languages used for

L’archive ouverte pluridisciplinaire HAL, est destinée au dépôt et à la diffusion de documents scientifiques de niveau recherche, publiés ou non, émanant des

The Liu, Magal, Seydi and Webb model has already been used to describe the evolution of the epidemic in various countries (China, South Korea, the United Kingdom, Italy, France