Note that the resulting circuit is a classical, reversible circuit
(more precisely, the circuit defines a one-to-one function). In
order to obtain a reversible quantum circuit, one should then apply
the function classical_to_reversible to get the following (we
keep the same convention of wires as in the definition of C):

A type of boolean parameters

During the construction of a quantum circuit from
classical code, the type Bool is mapped to the type
Qubit. However, it is also sometimes useful to specify boolean
parameters to be used during circuit generation (for example, in
the BWT algorithm, the color is a parameter). For this purpose, we
provide a new type BoolParam, which is identical to Bool in
most respects, except that it is not mapped to Qubit during
circuit generation.

Lifting classical functions to circuits

The main tool for transforming a classical computation into a
quantum circuit is the function decToCircMonad. It inputs the
syntax tree of a classical function, and outputs the syntax tree of
a corresponding quantum circuit. The type Bool is mapped to
Qubit; the type BoolParam is unchanged; and each function f :
a → b is mapped to a function f' : a' → Circb',
where a' and b' are the translations of the types a and b,
respectively.

Most of the work is done by the lower-level function
decToMonad from the module Libraries.Template.
This lower-level function knows how to deal with many usual
constructs of the Haskell language, such as function applications,
lambda-abstractions, let-assignments, case-distinctions, and so
on. However, decToMonad does not by default know how to deal
with the base cases, i.e., how to extract quantum circuits from
specific term constants such as &&, ||, etc.

The purpose of the remainder of this module is to do just that. For
every constant or function XXX that one may want to use in a
classical program, we provide an implementation template_XXX as a
quantum circuit. We refer to template_XXX as the "lifted"
version of XXX. The function decToCircMonad is a version of
decToMonad that knows about these liftings.

Input the syntax tree of a classical function, and output the
syntax tree of a corresponding quantum function. The type Bool is
mapped to Qubit; the type BoolParam is unchanged; and and each
function f : a → b is mapped to a function f' : a' →
Circb', where a' and b' are the translations of the types
a and b, respectively. The function decToCircMonad knows
about many built-in operations such as && and ||, whose
circuit translations are defined below.

Syntactic sugar

Quipper comes equipped with syntactic sugar to ease
the use of the decToCircMonad function.

Although the code

$( decToCircMonad [d| f x = ... |] )

is valid, it is possible to use the special keyword
build_circuit, as follows:

build_circuit
f x = ...

This code is equivalent to

f x = ...
$( decToCircMonad [d| f x = ... |] )

In other words, it generates both a function f of type a -> ...
and an object template_f of type Circ (a -> Circ ...).

Generic unpacking

The decToCircMonad function produces (and also requires)
functions with somewhat unwieldy types. The CircLiftingUnpack
class defines generic functions for unpacking these types into a
more useable format, and for packing them back.