Table Of ContentPreliminary Proceedings of the
2001 ACM SIGPLAN
Haskell Workshop
(HW’2001)
Firenze, Italy
2nd September 2001
Ralf Hinze (editor)
Technical Report UU-CS-2001-23
Institute of Information and Computing Sciences
Utrecht University
***
Foreword
This volume contains the preliminary proceedings of the 2001 ACM SIGPLAN Haskell Work-
shop, which was held on 2nd September 2001 in Firenze, Italy. The final proceedings will
publishedbyElsevierScienceasanissueofElectronicNotesinTheoreticalComputerScience
(Volume 59).
TheHaskellWorkshopwassponsoredbyACMSIGPLANandformedpartofthePLI2001
colloquium on Principles, Logics, and Implementations of high-level programming languages,
which comprised the ICFP/PPDP conferences and associated workshops. Previous Haskell
Workshops have been held in La Jolla (1995), Amsterdam (1997), Paris (1999), and Montr´eal
(2000).
ThepurposeoftheHaskellWorkshopwastodiscussexperiencewithHaskell, andpossible
future developments for the language. The scope of the workshop included all aspects of the
design, semantics, theory, application, implementation, and teaching of Haskell. Submissions
that discussed limitations of Haskell at present and/or proposed new ideas for future versions
ofHaskellwereparticularlyencouraged. AdoptinganideafromICFP2000,theworkshopalso
solicitedtwospecialclassesofsubmissions,applicationlettersandfunctionalpearls,described
below.
Application Letters AnapplicationletterdescribesexperienceusingHaskelltosolvereal-
world problems. Such a paper may be shorter than a regular paper (but need not be), and
and may be judged by interest of the application and novel use of Haskell.
Functional Pearls A functional pearl presents — using Haskell as a vehicle — an idea
that is small, rounded, and glows with its own light. Such a paper may be shorter than a
regular paper (but need not be), and may be judged by elegance of development and clarity
of expression.
The workshop received a total of 23 submissions and after careful consideration the pro-
gramme committee accepted 10 papers for presentation (6 regular, 4 functional pearls, and
no application letters). Each programme committee member reviewed ten papers, possibly
with the aid of an outside expert. Each paper was assigned to at least three reviewers. Fi-
nal decisions were made during a virtual programme committee meeting. The selection was
competitive: several good papers had to be rejected.
Ralf Hinze, Organizer and Chair
Utrecht, August 2001
Programme Committee
Manuel Chakravarty University of New South Wales
Jeremy Gibbons University of Oxford
Ralf Hinze (chair) University of Utrecht
Patrik Jansson Chalmers University
Mark Jones Oregon Graduate Institute
Ross Paterson City University, London
Simon Peyton Jones Microsoft Research
Stephanie Weirich Cornell University
Acknowledgements
The programme committee thanks the following people for their assistance in evaluating the
submissions:
Pablo Azero Andres L¨oh
Dennis Bj¨orklund Clare Martin
Magnus Carlsson Shin-Cheng Mu
James Cheney Johan Nordlander
David Clarke Claudio Russo
Iavor Diatchki Silvija Seres
J¨orgen Gustavsson Mark Shields
Thomas Hallgren Fred Smith
Bill Harrison Josef Svenningsson
Gabriele Keller Dave Walker
David Lacey Steve Zdancewic
Peter Ljunglo¨f
Special thanks are due to Andres L¨oh for his assistance in preparing the preliminary proceed-
ings and to Betti Venneri for her help with organizing the workshop.
Contents
Session I • 9.00 – 10.30: chaired by Ralf Hinze
Functional Pearl: Derivation of a Carry Lookahead Addition Circuit ............... 1
John O’Donnell and Gudula Ru¨nger
Functional Pearl: Inverting the Burrows-Wheeler Transform ...................... 33
Richard Bird and Shin-Cheng Mu
Genuinely Functional User Interfaces ............................................ 41
Antony Courtney and Conal Elliott
10.30 - 11.00:
Coffee break
Session II • 11.00 - 12.30: chaired by Patrik Jansson
Named Instances for Haskell Type Classes ........................................ 71
Wolfram Kahl and Jan Scheffczyk
A Functional Notation for Functional Dependencies ............................. 101
Matthias Neubauer, Peter Thiemann, Martin Gasbichler, and Michael Sperber
Report from the program chair and 10-minute talks
12.30 - 14.00:
Lunch
Session III • 14.00 - 15.30: chaired by Ross Paterson
GHood - Graphical Visualisation and Animation of Haskell Object Observations . 121
Claus Reinke
Multiple-View Tracing for Haskell: a New Hat .................................. 151
Malcolm Wallace, Olaf Chitil, Thorsten Brehm, and Colin Runciman
10-minute talks
15.30 - 16.00:
Coffee break
Session IV • 16.00 - 17.30: chaired by Jeremy Gibbons
Functional Pearl: Parsing Permutation Phrases ................................. 171
Arthur Baars, Andres L¨oh, and S. Doaitse Swierstra
Functional Pearl: Pretty Printing with Lazy Dequeues ........................... 183
Olaf Chitil
Playing by the Rules: Rewriting as a practical optimisation technique in GHC ... 203
Simon Peyton Jones, Andrew Tolmach, and Tony Hoare
Session V • 17.30 - 18.00: chaired by Manuel Chakravarty
Discussion: the future of Haskell
***
Functional Pearl
Derivation of a Carry Lookahead
Addition Circuit
John O’Donnell1,2
Computing Science Department
University of Glasgow
Glasgow, United Kingdom
Gudula Ru¨nger3
Fakult¨at fu¨r Informatik
Technische Universit¨at Chemnitz
Chemnitz, Germany
Abstract
Using Haskell as a digital circuit description language, we transform a ripple carry
adder that requires O(n) time to add two n-bit words into an efficient carry looka-
headadderthatrequiresO(logn)time. Thegaininspeedreliesontheuseofparallel
scantocalculatethepropagationofcarrybitsefficiently. Themaindifficultyisthat
this scan cannot be parallelised directly since it is applied to a non-associative func-
tion. Severaladditionaltechniquesareneededtocircumventtheproblem, including
partial evaluation and symbolic function representation. The derivation given here
provides a formal correctness proof, yet it also makes the solution more intuitive by
bringing out explicitly each of the ideas underlying the carry lookahead adder.
1 Introduction
In this paper we use Haskell as a digital circuit description language in order
to solve an important problem in hardware design: the transformation of a
ripple carry adder that requires O(n) time to add two n-bit words into a carry
1 This work was supported in part by the British Council and the Deutsche Akademische
Austauschdienst under the Academic Research Collaboration program.
2 Email: jtod@dcs.gla.ac.uk Web: www.dcs.gla.ac.uk/∼jtod/
3 Email: ruenger@informatik.tu-chemnitz.de
Web: www.tu-chemnitz.de/informatik/HomePages/PI/index.html
1
O’Donnell and Ru¨nger
lookahead adder, which needs only O(logn) time. This problem has great
practical importance, since the clock speed of synchronous digital circuits is
determined by the critical path depth, and an adder lies on the critical path
in typical processor datapath architectures. In other words, by speeding up
just an adder, which accounts for a few hundred logic gates, the speed of an
entire chip with millions of gates can be improved.
The circuit that we design here is not new; it is related to (though different
from) a circuit by Ladner and Fischer [7] (1980), and the particular variation
that we develop is essentially the same as the one presented in the well known
textbook on algorithms by Cormen, Leiserson and Rivest [3]. The original
contributions of this paper include the formal specification, the correctness
proof, and the derivation:
• Our derivation produces a precise specification of the circuit, which can be
simulated or fabricated automatically. The earlier presentations give only
examples of the circuit at particular word sizes, relying on the reader to
figure out other cases. This can be surprisingly difficult, and is unsuitable
for modern integrated circuit design, which is highly automated.
• The derivation produces a general solution that works on word size n for
every natural number n.
• The carry lookahead adder is usually presented as a large and very compli-
cated circuit, which is quite difficult to understand. In contrast, we explain
it by going through a sequence of transformation steps. At each stage there
is a specific technical problem to overcome and a clear strategy for solving
it. This leads to a better understanding than contemplation of the final
design, where several quite distinct ideas are mixed together and buried in
a large network of logic gates.
• The derivation in this paper provides a correctness proof for the adder.
Although we do not claim the circuit derived here to be new, there is a sense
in which it actually is new. The adders presented before operate only on
fixed size words, but we derive a family of adders defined for every wordsize
n ∈ Nat. For example, the adder described in [3] takes two 8-bit words and
producesan8-bitsum. It does not work at all for any other word size. Itstime
complexity is O(1); indeed, it is meaningless to attribute a time complexity
of O(logn) to an algorithm that lacks a parameter n.
Clearly the authors of the previous papers could have designed an adder
at a different fixed word size, say 16. What they did not do was to design
a general adder at size n, and there is a good reason: they did not use a
formalism capable of expressing families of parameterised circuits.
Inthispaper,weuseHydra[10],acomputerhardwaredescriptionlanguage
(CHDL) embedded in Haskell. Two advantages of Hydra are central to the
paper: it allows circuit patterns to be defined, allowing n-bit circuits, and it
allows formal equational reasoning to be used in transforming circuits. The
reader is assumed to be familiar with Haskell but not with Hydra, and the
2
O’Donnell and Ru¨nger
essentialmethodsoffunctionalhardwarespecificationwillbeexplainedbelow.
Links to further information on Hydra can be found on the web page for this
paper:
http://www.dcs.gla.ac.uk/∼jtod/papers/2001 Adder/
A huge benefit of CHDLs is their ability to define families of related cir-
cuits. Most CHDLs are based on imperative programming, but functional
languages work far better for this application domain. In particular, this pa-
per relies on three characteristic features of functional languages: (1) higher
order functions express circuit patterns; (2) referential transparency supports
equational reasoning; (3) strong typing allows the circuit types to be defined
naturally, and also supports the wide variety of software tools provided by Hy-
dra. Nonstrict semantics (lazy evaluation) is also essential to Hydra, although
it happens not to be needed for the adder.
Eveninaformalderivation, examplesarehelpful, andthereaderisencour-
aged to experiment with a Haskell 98 program containing all the definitions in
this paper. The program contains test drivers that run a number of examples,
as well as comments explaining how to run it, and can be downloaded from
the web page mentioned above.
Athemerunningthroughthispaperisthedistinctionbetweenspecification
and implementation. For a number of auxiliary definitions, as well as for the
main result, the paper will begin with a clear specification and proceed to
derive an efficient implementation. There is no need for the specification to
be efficient, or for the implementation to be clear.
A related point is the distinction between circuit specifications and com-
puter programs. The Hydra language is intended specifically for circuit design,
and it is restricted to forms that correspond directly to circuits. The imple-
mentation of Hydra provides tools that will convert a circuit specification
(including all the adders defined in this paper) into netlists. Hydra is imple-
mented by embedding it in Haskell, so circuit specifications have the same
syntax as Haskell. However, Hydra is not identical to Haskell, and a designer
who forgets this may write a Haskell program that does not specify a digi-
tal circuit at all. This form of confusion has nothing to do with the design
of Hydra or Haskell; similar problems arise with imperative CHDLs such as
VHDL.
Section2definespreciselytheproblemtobesolved, givingaformalspecifi-
cation of a binary addition circuit and also explaining how we will use Haskell
to describe circuits. Section 3 introduces the combinators that will be used to
specifycircuitpatterns, andSection 4presentsthestandardripplecarryadder
in this style, using a scan combinator to handle the carry propagation. The
essential technique for speeding up the adder is parallel scan, which is derived
formally in Section 5. However, it turns out that the particular scan used in
the ripple carry adder cannot be implemented by the parallel scan algorithm
because it uses a non-associative function. Section 6 solves that problem us-
3
O’Donnell and Ru¨nger
ing partial evaluation. However, this introduces a new difficulty: the “circuit”
now operates on functions as well as signals, and is no longer a circuit at all.
Section 7 introduces a symbolic function representation, Section 8 introduces
parallelism into the adder, Section 9 takes care of the final hardware details,
and Section 10 concludes.
2 The Problem
A signal is a bit in a digital circuit; for the purposes of this paper a signal can
be thought of as a value of type Bool. The function bit :: Signal a ⇒ a → Nat
converts a bit value to its natural value, either 0 or 1.
A binary number is represented as a list of signals [x ,...,x ] that con-
0 n−1
stitute an n-bit word, where x is the most significant bit and x the least
0 P n−1
significant. The value represented by this word is bin xs = n−1x 2n−1−i.
i=0 i
It is assumed throughout this paper that all lists have finite length. Some
of the results need to be refined to handle infinite data structures, but issues
of strictness are irrelevant to the derivation of the adder.
A binary adder takes a pair of n-bit words xs and ys and a carry input
bit c, and it produces their sum, represented as a carry output bit c0 and an
n-bit sum ss. Instead of giving the adder two separate words xs and ys, it
will receive a word zs :: Signal a ⇒ [(a,a)] of pairs. The binary input words
are then map fst zs and map snd zs. There are two reasons for choosing this
organisation: it avoids the need for stating side conditions that xs and ys have
the same length, and it simplifies the circuits we will define later. But we are
not cheating—it is a standard technique in hardware design (called “bit slice”
organisation) to zip the two words together in this way, because of exactly the
same simplification to the design.
An adder is now defined to be any circuit with the right type that produces
the right answer for arbitrary inputs.
Definition 2.1 (Adder) Let a be a signal type. An adder is a function add
such that
add :: Signal a ⇒ a → [(a,a)] → (a,[a]),
∀c :: a, zs :: [(a,a)] .
2n ·bit c0 +bin ss = bin (map fst zs)+bin (map snd zs)+bit c
where
(c0,ss) = add c zs
n = length zs = length ss.
Circuits will be specified in this paper using Hydra [10], a digital circuit
specification language embedded within Haskell. Signals are defined as a type
class that provides basic operations, such as the constant values zero and
one and basic logic gates, including the inverter inv, the two and three input
4