Haskell-cover+spine.qxd 8/13/2004 1:59 PM Page 1 H a s Haskell’04 k e l l ’ 0 4 A C M S Proceedings of the IG P L A ACM SIGPLAN N 2 0 0 4 H 2004 Haskell Workshop a s k e ll W o r k s h o p • S e p September 22, 2004 t . 2 Snowbird, Utah, USA 2 , 2 0 0 4 • S n o w b ir d , U ta h , U Co-located with ICFP’04 S A Haskell’04 Proceedings of the ACM SIGPLAN 2004 Haskell Workshop September 22, 2004 Snowbird, Utah, USA Co-located with ICFP’04 The Association for Computing Machinery 1515 Broadway New York, New York 10036 Copyright © 2004 by the Association for Computing Machinery, Inc. (ACM). Permission to make digital or hard copies of portions of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. Copyright for components of this work owned by others than ACM must be honored. Abstracting with credit is permitted. To copy otherwise, to republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee. Request permission to republish from: Publications Dept., ACM, Inc. Fax +1 (212) 869-0481 or <[email protected]>. For other copying of articles that carry a code at the bottom of the first or last page, copying is permitted provided that the per-copy fee indicated in the code is paid through the Copyright Clearance Center, 222 Rosewood Drive, Danvers, MA 01923. Notice to Past Authors of ACM-Published Articles ACM intends to create a complete electronic archive of all articles and/or other material previously published by ACM. If you have written a work that has been previously published by ACM in any journal or conference proceedings prior to 1978, or any SIG Newsletter at any time, and you do NOT want this work to appear in the ACM Digital Library, please inform [email protected], stating the title of the work, the author(s), and where and when published. ISBN: 1-58113-850-4 Additional copies may be ordered prepaid from: ACM Order Department PO Box 11405 New York, NY 10286-1405 Phone: 1-800-342-6626 (US and Canada) +1-212-626-0500 (all other countries) Fax: +1-212-944-1318 E-mail: [email protected] ACM Order Number 565042 Printed in the USA ii Foreword It is my great pleasure to welcome you to the ACM SIGPLAN 2004 Haskell Workshop. The purpose of the Haskell Workshop is to discuss experience with Haskell, and possible future developments for the language. The scope of the workshop includes all aspects of the design, semantics, theory, application, implementation, and teaching of Haskell. The 2004 Haskell Workshop takes place on 22 September, 2004, in Snowbird, Utah, USA, in affiliation with the 2004 International Conference on Functional Programming (ICFP'04). The call for papers attracted 27 submissions. Each paper was evaluated by at least three international referees. During a five-day electronic meeting, the program committee selected nine of the submissions for presentation at the workshop as full papers based on the referee reports. The program committee also selected a student paper for a short presentation. Additionally, two tool demonstrations, the abstracts of which are included in these proceedings, were selected from five proposals. The 2004 workshop program also includes the annual The Future of Haskell discussion. Putting together the 2004 Haskell Workshop was very much a team effort. First of all, I would like to thank the authors for providing the content of the program. Then I would like to thank the program committee and the additional reviewers who put a lot of effort into evaluating the submissions and providing constructive feedback to the authors. Finally, I would like to thank Franklyn A. Turbak, the ICFP'04 Workshops Chair, and Lisa M. Tolles, Sheridan Printing, for their help with organizing the workshop and producing the proceedings. Henrik Nilsson Björstorp, Sweden, July 2004 iii Table of Contents Haskell 2004 Workshop Organization..................................................................................................vi 9:00–10:30 • Session 1 • Functional Pearl: I am not a Number—I am a Free Variable...................................................................1 C. McBride (University of Durham), J. McKinna (University of St Andrews) • Plugging Haskell In.........................................................................................................................................10 A. Pang (Information & Communication Technologies), D. Stewart, S. Seefried, M. M. T. Chakravarty (University of New South Wales) • Extending the Haskell Foreign Function Interface with Concurrency...............................................22 S. Marlow, S. Peyton Jones (Microsoft Research Ltd.), W. Thaller 11:00–12:30 • Session II • Functional Pearl: Implicit Configurations—or, Type Classes Reflect the Values of Types.........................................................................................................................................33 O. Kiselyov (Fleet Numerical Meteorology and Oceanography Center), C.-c. Shan (Harvard University) • Programming Graphics Processors Functionally...................................................................................45 C. Elliott • wxHaskell—A Portable and Concise GUI Library for Haskell..............................................................57 D. Leijen (Utrecht University) 14:00–15:30 • Session III • Type-Safe, Self Inspecting Code.................................................................................................................69 A. I. Baars, S. D. Swierstra (Utrecht University) • Improving Type Error Diagnosis.................................................................................................................80 P. J. Stuckey (University of Melbourne), M. Sulzmann (University of Singapore), J. Wazny (University of Melbourne) • Demonstration Abstract: Haskell Type Browser.....................................................................................92 M. Neubauer, P. Thiemann (Universität Freiburg) • Demonstration Abstract: BNF Converter..................................................................................................94 M. Forsberg, A. Ranta (Chalmers University of Technology and the University of Gothenburg) 16:00–17:30 • Session IV • Strongly Typed Heterogeneous Collections............................................................................................96 O. Kiselyov (FNMOC), R. Lämmel (VU & CWI), K. Schupke (Imperial College) • Student Paper: HaskellDB Improved........................................................................................................108 B. Bringert, A. Höckersten (Chalmers University of Technology) Author Index......................................................................................................................................................116 v 2004 Haskell Workshop Organization Chair: Henrik Nilsson (University of Nottingham, UK) Program Committee: Jörgen Gustavsson (Chalmers University of Technology, Sweden) Thomas Hallgren (OGI, Oregon Health & Science University, USA) Jerzy Karczmarczuk (Université de Caen, France) Daan Leijen (Universiteit Utrecht, The Netherlands) Colin Runciman (University of York, UK) Martin Sulzmann (National University of Singapore, Singapore) Valery Trifonov (Yale University, USA) Additional reviewers: Thorsten Altenkirch Arthur Baars Olaf Chitil Andres Löh Kenny Zhuo Ming Lu Ulf Norell Simon Peyton-Jones Bernard James Pope Fermin Reig Ognyan Stoyanov Jeremy Wazny Joel Wright vvi i Functional Pearl: I am not a Number—I am a Free Variable ConorMcBride JamesMcKinna DepartmentofComputerScience SchoolofComputerScience UniversityofDurham UniversityofStAndrews SouthRoad,Durham,DH13LE,England NorthHaugh,StAndrews,KY169SS,Scotland [email protected] [email protected] Abstract 1 Introduction Inthispaper,weshowhowtomanipulatesyntaxwithbindingusing This paper is about our everyday craft. It concerns, in particu- amixedrepresentationofnamesforfreevariables(withrespectto lar, naming in the implementation of systems which manipulate thetaskinhand)anddeBruijnindices[5]forboundvariables. By syntax-with-binding. The problems we address here are not so doing so, we retain the advantages of both representations: nam- much concerned with computations within such syntaxes as con- ingsupportseasy,arithmetic-freemanipulationofterms;deBruijn structionsover them. Forexample,giventhedeclarationofanin- indiceseliminatetheneedforα-conversion. Further,wehaveen- ductive datatype (by declaring the types of its constructors), how suredthatnotonlytheuserbutalsotheimplementationneednever mightoneconstructitsinductionprinciple? dealwithdeBruijnindices,exceptwithinkeybasicoperations. WeencountersuchissuesallthetimeintheimplementationofEPI- Moreover, we give a hierarchical representation for names which GRAM [19]. But even as we develop new technology to support naturally reflects the structure of the operations we implement. programmingandreasoninginadvancedtypesystems,butwemust Namechoiceissafeandstraightforward.Ourtechnologycombines handletheissuestheyraiseeffectivelywithtoday’stechnology.We easilywithanapproachtosyntaxmanipulationinspiredbyHuet’s work in Haskell and so do our students. When they ask us what ‘zippers’[10]. toreadinordertolearntheirtrade,wetendtolookblankandfeel guilty.Wewanttodosomethingaboutthat. Withouttheideasinthispaper,wewouldhavestruggledtoimple- mentEPIGRAM[19]. Ourexample—constructinginductiveelimi- Let’slookattheexampleofconstructinganinductionprinciplefor nationoperatorsfordatatypefamilies—isbutoneofmanywhereit adatatype.Supposesomeonedeclares provesinvaluable. dataNat = Zero|SucNat CategoriesandSubject Descriptors Weshouldliketosynthesizesomestatementcorrespondingto I.1.1 [Symbolic and Algebraic Manipulation]: Expressions and Their Representation; D.1.1 [Programming Techniques]: Ap- plicative(Functional)Programming ∀P∈Nat→Prop. PZero → (∀k∈Nat.Pk→P(Suck)) → GeneralTerms ∀n∈Nat.Pn Languages,Design,Reliability,Theory In a theoretical presentation, we need not concern ourselves too much about where these names come from, and we can always Keywords choose them so that the sense is clear. In a practical implemen- tation,wehavetobemorecautious—theuser(innocentlyorother- Abstract syntax, bound variables, de Bruijn representation, free wise)maydecidetodeclare variables,freshnames,Haskell,implementingEpigram,induction principles dataNat = Zero|PNat oreven dataP = Zero|SucP We’llhavetobecarefulnottoendupwithsuchnonsenseas ∀P∈Nat→Prop. or ∀P∈P→Prop. PZero → PZero → Permissiontomakedigitalorhardcopiesofallorpartofthisworkforpersonalor (∀k∈Nat.Pk→P(Pk)) → (∀k∈P.Pk→P(Suck)) → classroomuseisgrantedwithoutfeeprovidedthatcopiesarenotmadeordistributed ∀n∈Nat.Pn ∀n∈P.Pn forprofitorcommercialadvantageandthatcopiesbearthisnoticeandthefullcitation onthefirstpage.Tocopyotherwise,torepublish,topostonserversortoredistribute tolists,requirespriorspecificpermissionand/orafee. Fearofshadowsmayseemtrivial,butit’snojoke—somerealsys- Haskell’04,September22,2004,Snowbird,Utah,USA. Copyright2004ACM1-58113-850-4/04/0009...$5.00 temshavethisbug,althoughitwouldbeinvidioustonamenames. 1 Possible alternative strategies include the adoption of one of de boundvariablesaredistinguishedfromfreevariablesbutnonethe- Bruijn’ssystemsofnamelessdummies[5]forthelocalquantifiers, less named. We draw on the Huet’s ‘zipper’ technique [10] to eithercountingbinders(including→,whichwetaketoabbreviate∀ help us write programs which navigate and modify the structure wheretheboundvariableisn’tused)fromthereferenceoutward— of terms. Huetequips syntax with anauxiliary datatype of struc- deBruijnindices, turalcontexts. Inourvariationonhistheme,werequirenamingas wenavigateunderbinderstoensurethatastructuralcontextisalso ∀−∈Nat→Prop. alinguisticcontext. Ineffect,whoever‘I’maybe,ifIaminvolved 0Zero → inthediscourse,thenIamnotanumber—Iamafreevariable. (∀−∈Nat.20→3(Suc1)) → Withmanyagentsnowengagedinthebusinessofnaming,weneed ∀−∈Nat.30 a representation of names which readily supports the separation ofnamespacesbetweenmechanicalconstructionagentswhichcall orfromtheoutsideinward—deBruijnlevels. each other and indeed themselves. We adopt a hierarchical nam- ingsystemwhichpermitsmultipleagentstochoosemultiplefresh ∀0∈Nat→Prop. namesinanotionallyasynchronousmanner,withoutfearofclash- 0Zero → ing.Ourdesignchoiceisunremarkableinthelightofhowhumans (∀2∈Nat.02→0(Suc2)) → addresssimilarissuesinthedesignoflargecomputersystems.Both ∀3∈Nat.03 theendsandthemeansofexploitingnamesinhumandiscoursebe- comenolesspertinentwhenthediscourseismechanical. It’sunfairtoobjectthattermsindeBruijnsyntaxareunfitforhu- Astheaboveexamplemaysuggest, wedevelopourtechniquesin manconsumption—theyarenotintendedtobe.Theirmainbenefits thispaper forafragmentofarelationallogic,featuringvariables, lie in their uniform delivery of capture-avoiding substitution and application, and universal quantification. It can also be seen as a their systematic resolution of α-equivalence. Our enemies can’t non-computationalfragmentofadependenttypetheory.We’vede- choosebadnamesinordertomaketrouble. liberatelyavoidedacomputationallanguageinordertokeepthefo- cusonconstruction,butyoucan—andeverydaywedo—certainly However,wedorecommendthatanyoneplanningtousedeBruijn applythesameideastoλ-calculi. syntax for systematic constructions like the above should think again. Performingconstructionsineitherofthesesystemsrequires alotofarithmetic. Thisobscurestheideabeingimplemented,re- Overview sultsinunreadable,unreliable,unmaintainablecode,andisbesides hardwork.We,orratherourprograms,can’tchoosegoodnamesin Insection2ofthispaper, wegivetheunderlying datarepresenta- ordertomakesense. tionforourexamplesyntaxanddevelopthekeyoperationswhich manipulate bound variables—only here do we perform arithmetic Amixedrepresentationofnamesprovidesaremedy. Inthispaper, ondeBruijnindices, andthatislimitedtotrackingtheoutermost wenamefreevariables(ie,variablesboundinthecontext)sothat indexaswerecurseunderbinders. wecanrefertothemandrearrangethemwithouttheneedtocount; we give bound variables de Bruijn indices to ensure a canonical Section 3 shows the development of our basic construction and meansofreferencewherethere’sno‘socialagreement’onaname. analysis operators for the syntax, and discusses navigation within expressionsinthestyleofHuet[10]. Section4introducesourhi- The distinction between established linguistic signs, connecting a erarchicaltechniquefornamingfreevariablesinharmonywiththe signifiant (or‘signifier’)withitssignifie´ (or‘signified’),andlocal call-hierarchyofagentswhichmanipulatesyntax. signs, where theparticular choice of signifierisarbitrary wasob- servedinthecontextofnaturallanguagebySaussure[6].Informal ThesecomponentscometogetherinSection5,whereweassemble languages,theideaofdistinguishingfreeandboundvariablessyn- a high-level toolkit for constructions over our syntax. Section 6 tactically is also far from new. It’sa recurrent idiom in the work putsthistoolkittoworkinanon-trivialexample: theconstruction ofGentzen [8], Kleene[14]and Prawitz[24]. Thesecond author ofinductionprinciplesforEPIGRAM’sdatatypefamilies[7,15,19]. learneditfromRandyPollackwholearneditinturnfromThierry Coquand[4];thefirstauthorlearneditfromthesecond. Acknowledgements Theideaofusingfreenamesandboundindicesisnotneweither— it’sacommonrepresentationininteractiveproofsystems.Thisalso The earliest version of the programs we present here dates back comestotheauthorsfromRandyPollack[23]whocitestheinflu- to 1995—our Edinburgh days—and can still be found in the ence of Ge´rard Huet in the Constructive Engine [9]. Here ‘free’ source code for LEGO version 1.3, in a file named inscrutably means ‘bound globally inthecontext’ and‘bound’ means‘bound conor-voodoo.sml. Our influences are date back much further. locally in the goal’. The distinction is allied to the human user’s Weshouldliketothankallofourfriendsandcolleagueswhohave perspective—theuserprovesanimplicationbyintroducingthehy- encouraged us and fed us ideas through the years, in particular pothesis to the context, naming it H for easy reference, although Ge´rardHuetandThierryCoquand. other names are, we hear, permitted. By doing so, the user shifts perspective toone which islocally more convenient, even though The first author would also like to thank the Foundations of Pro- theresultingproofisintendedtoapplyregardlessofnaming. gramming group at the University of Nottingham who provided the opportunity and the highly interactive audience for the infor- What’s new in this paper is the use of similar perspective shifts mal ‘Life Under Binders’ course in which this work acquired its to support the use of convenient naming in constructions where presenttutorialform. the ‘user’ is itself a program. These shifts are similar in charac- tertothoseusedbythesecondauthor(withRandyPollack)when SpecialthanksmustgotoRandyPollack,fromwhoseconversation formalizing Pure Type Systems [20, 21], although in that work, andcodewehavebothlearnedagreatdeal. 2 2 An ExampleSyntax Meanwhile, instantiateimageturnsascopeintoanexpressionby replacingtheouterdeBruijnindex(initiallyB0)withimage,which Today, letushavevariables, application, anduniversalquantifica- wepresumeisclosed. Ofcourse,Fnameisclosed,sowecanuse tion.Wechooseanentirelyfirst-orderpresentation:1 instantiate(Fname)toinvertabstractname. infixl9:$ instantiate :: Expr → Scope → Expr infixr6:→ instantiateimage(Scbody) = replace0body where dataExpr = FName —freevariables replaceouter (Bindex)|index==outer=image | BInt —boundvariables |otherwise =Bindex | Expr:$Expr —application replaceouter (Fname) =Fname | Expr:→Scope —∀-quantification replaceouter (fun:$arg) = deriving(Show,Eq) replaceouterfun:$replaceouterarg replaceouter (dom:→Scbody) = newtypeScope = ScopeExpr deriving(Show,Eq) replaceouterdom:→ Sc(replace(outer+1)body) Weshall define Namelater—fornow, letus atleastpresume that NotethatthechoiceofanunsophisticateddeBruijnindexedrepre- itsupportsthe(==)test. Observethatexpressionsoveracommon sentationallowsustore-usetheclosedexpressionimage,however contextoffreeNamescanmeaningfullybecomparedwiththeor- manyboundvariableshavebecomeavailablewhenitisbeingref- dinary(==)test—α-conversionisnotanissue. erenced. Somereadersmaybefamiliarwiththeuseofnesteddatatypesand Itisperfectlyreasonabletodeveloptheseoperationsforotherrep- polymorphicrecursiontoenforcescopeconstraintspreciselyifyou resentationsofboundvariables,justaslongasthey’restillkeptsep- parametrize expressions by names [2, 3]. Indeed, with a depen- aratefromthefreevariables. AdeBruijnlevelrepresentationstill dently typedmeta-language it’snotsohard toenforceboth scope hasthebenefitofcanonicalname-choiceandcheapα-equivalence, andtypeforanobject-language[1]. Theseadvancedtypesystems but it does mean that image must be shifted one level when we canandshouldbeusedtogivemoreprecisetypestotheprograms push it under a binder. Moreover, if we were willing to pay for inthispaper,buttheywouldservehereonlytodistractreadersnot α-equivalence and fresh-name generation forbound variables, we yethabituatedtothosesystemsfromtheimplementationtechniques could even use names, modifying thedefinition of Scope to pack whichweseektocommunicatehere. themup. Wefeelthat,whetherornotyouwanttoknowthenames ofboundvariables,it’sbettertoarrangethingssoyoudon’thaveto Nonetheless, we do introduce a cosmetic type distinction to help careaboutthenamesofboundvariables. usrememberthatthescopeofabindermustbeinterpreteddiffer- ently. TheScopetypestandsinlieuoftheprecise‘termoverone Thosewithaneyeforageneralizationwillhavespottedthatboth more variable’ construction. For the most part, we shall pretend abstractandinstantiatecanbeexpressedasinstancesofasingle that Expr is the type of closed expressions—those with no ‘dan- general-purpose higher-order substitution operation, parametrized gling’ bound variables pointing out of scope, and that Scope has by arbitrary operations on free and bound variables, themselves onedanglingboundvariable,calledB0atthetoplevel. Inorderto parametrizedbyouter. supportthispretence,however,wemustfirstdevelopthekeyutili- tieswhichtradebetweenfreeandboundvariables,providingahigh levelinterfacetoScope.Weshallhave varChanger :: (Int→Name →Expr) → (Int→Int →Expr) → abstract ::Name → Expr → Scope Expr → Expr instantiate::Expr → Scope → Expr Wemightwelldothisinpractice,toreducethe‘boilerplate’code Theoperationabstractnameturnsaclosedexpressionintoascope requiredbytheseparatefirst-orderdefinitions. However,thisoper- byturningnameintoB0. Ofcourse,aswepushthisoperationun- ationisunsafeinthewronghands. derabinder, thecorrectindexfornameshiftsalongbyone. That Another potential optimization, given that we often iterate these is,theimageofnameisalwaystheouterdeBruijnindex,hencewe operations, is to generalize abstract, so that it turns a sequence implementabstractviaahelperfunction whichtracksthisvalue. of names into dangling indices, and correspondingly instantiate, Observethattheexistingboundvariableswithinexpr’sScopesre- replacing dangling indices withasequence ofclosed expressions. mainuntouched. Weleavethisasanexerciseforthereader. abstract :: Name → Expr → Scope Fromnowon,outsideoftheseoperations,wemaintaintheinvariant abstractnameexpr = Sc(nameTo0expr) where thatExprisonlyusedforclosedexpressionsandthatScopeshave nameToouter (Fname(cid:6))|name==name(cid:6)=Bouter justonedanglingindex.ThedataconstructorsBandSchaveserved |otherwise =Fname(cid:6) theirpurpose—we forbid any furtheruse ofthem. Fromnow on, nameToouter (Bindex) =Bindex therearenodeBruijnnumbers,onlyfreevariables. nameToouter (fun:$arg) = It’s trivial to define substitution for closed expressions using nameToouterfun:$nameToouterarg nameToouter (dom:→Scbody) = abstractandinstantiate(naturally,thisalsoadmitsalesssuccinct, nameToouterdom:→ Sc(nameTo(outer+1)body) moreefficientimplementation): 1Thetechniquesinthispaperadaptreadilytohigher-orderrep- substitute :: Expr → Name → Expr → Expr resentationsofbinding,butthat’sanotherstory. substituteimagename = instantiateimage · abstractname 3 Next,letusseehowinstantiateandabstractenableustonavigate underbindersandbackoutagain,withouteverdirectlyencounter- ingadeBruijnindex. infixl4 :< dataStackx = Empty|Stackx :< x deriving(Show,Eq) typeZipper = StackStep 3 BasicAnalysisand ConstructionOperators dataStep=Fun()Expr Wemayreadilydefineoperatorswhichattempttoanalyseexpres- |ArgExpr() sions, safely combining selection (testing which constructor is at |Dom()Scope the head) with projection (extracting subexpressions). Haskell’s |RangeBinding() support formonads givesusaconvenient means tohandle failure whenthe‘wrong’constructorispresent. Inverting(:$)isstraight- This zipper structure combines the notions of structural and lin- forward: guisticcontext—aZippercontainsthebindingsforthenameswhich mayappearinanyExprfillingthe‘hole’. Notethatwedon’tbind the variable when we edit a domain: it’s not in scope. We can unapply :: MonadPlusm ⇒Expr → m(Expr,Expr) easily edit these zippers, inserting new bindings (e.g., for induc- unapply(fun:$arg)=return(fun,arg) tivehypotheses)orpermutingbindingswheredependencypermits, unapply =mzero withoutneedingtorenumberdeBruijnvariables. By contrast, editing with the zipper constructed with respect to the raw definition of Expr—moving into scopes without binding Forourquantifier,however, wecombinestructuraldecomposition variables—often requires a nightmare of arithmetic. The first au- withthenamingoftheboundvariable.Ratherthansplittingaquan- thorbangedhisheadonhisMaster’sproject[16]thisway,before tifiedexpressionintoadomainandaScope,weshallextractabind- thesecondauthorcaughthimatit. ingandtheclosedExprrepresentingtherange.Weintroduceaspe- cial type of pairs which happen to be bindings, rather than using Thezipperconstructionprovidesageneral-purposepresentationof ordinary tuples, justtomake theappearance ofprograms suitably navigationwithinexpressions—that’s astrength whenweneed to suggestive.WeequipBindingwithsomeusefulcoercions. copewithnavigationchoicesmadebyanexternalagency,suchas the user of a structure editor. However, it’sa weakness when we wish tosupport more focused editingstrategies. Inwhat follows, infix5 :∈ we’llbe working not with thezipper itself, butwith specificsub- dataBinding = Name :∈ Expr typesofit,representingparticularkindsofone-holecontext,such as‘quantifierprefix’or‘argumentsequence’. Correspondingly,the bName :: Binding → Name operationswedevelopshouldbeseenasspecializationsofHuet’s. bName(name :∈ ) = name But hold on a moment! Before we can develop more systematic bVar :: Binding → Expr editing tools, we must address the fact that navigating under a bVar = F·bName binderrequiresthesupplyofaName. Whereisthisnametocome from? Howisittoberepresented? Whathastheformertodowith thelatter?Let’snowconsidernaming. Nowwecandevelopa‘smartconstructor’whichintroducesauni- versalquantifierbydischargingabinding,anditsmonadicallylifted 4 OnNaming inverter: It’s not unusual to find names represented as elements of String. However, for our purposes, that won’t do. String does not have infixr6 −→ enough structure to reflect the way names get chosen. Choosing (−→) :: Binding → Expr → Expr distinct names is easy if you’re the only person doing it, because (name :∈ dom)−→range = dom:→abstractnamerange youcandoitdeliberately.However,ifthereismorethanoneagent choosingnames,weencounterthepossibilitythattheirchoiceswill infix ←− overlapbyaccident. (←−) :: MonadPlusm ⇒ Name → Expr → m(Binding,Expr) name←−(dom:→scope)=return(name :∈ dom, The machine must avoid choosing names already reserved by the instantiate(Fname)scope) user,whetherornotthosenameshaveyetappeared. Moreover,as name←− =mzero ourprogramsdecomposetasksintosubtasks,wemustavoidnam- ingconflictsbetweenthesubprogramswhichaddressthem.Indeed, wemustavoidnamingconflictsarisingfromdifferentappealstothe samesubprogram. 3.1 Inspiration—the ‘Zipper’ Howdoweachievethis? Onewayistointroduceaglobalsymbol Wecangiveanaccountofone-holecontextsinthestyleofHuet’s generator,manglingnamestoensuretheyaregloballyunique;an- ‘zippers’[10].AZipperisastack,storingtheinformationrequired otherapproachrequiresaglobalcounter,incrementedeachtimea to reconstruct an expression tree from a particular subexpression nameischosen. Thisstate-basedapproachfillsnameswithmean- at each step on the path back to the root. The operations defined inglessnumbers, anditunnecessarily sequentializestheexecution aboveallowustodevelopthecorrespondingone-stepmanoeuvres of operations—a process cannot begin togenerate names untilits uniformlyoverthetype(Zipper,Expr). predecessorshavefinisheddoingso. 4