Skip to content

Commit e1b53ab

Browse files
committed
Backpack documentation in the user manual.
Fixes #4761 Signed-off-by: Edward Z. Yang <[email protected]> [ghstack-poisoned]
1 parent a23c7a9 commit e1b53ab

File tree

2 files changed

+106
-2
lines changed

2 files changed

+106
-2
lines changed

doc/cabal-package.rst

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3333,6 +3333,112 @@ a few options:
33333333
library for all or part of the work. One option is to copy the source
33343334
of ``Distribution.Simple``, and alter it for your needs. Good luck.
33353335
3336+
Backpack
3337+
--------
3338+
3339+
Cabal and GHC jointly support Backpack, an extension to Haskell's module
3340+
system which makes it possible to parametrize a package over some
3341+
modules, which can be instantiated later arbitrarily by a user. This
3342+
means you can write a library to be agnostic over some data
3343+
representation, and then instantiate it several times with different
3344+
data representations. Like C++ templates, instantiated packages are
3345+
recompiled for each instantiation, which means you do not pay any
3346+
runtime cost for parametrizing packages in this way. Backpack modules
3347+
are somewhat experimental; while fully supported by cabal-install, they are currently
3348+
`not supported by Stack <https://github.com/commercialhaskell/stack/issues/2540>`__.
3349+
3350+
A Backpack package is defined by use of the
3351+
:pkg-field:`library:signatures` field, or by (transitive) dependency on
3352+
a package that defines some requirements. To define a parametrized
3353+
package, define a signature file (file extension ``hsig``) that
3354+
specifies the signature of the module you want to parametrize over, and
3355+
add it to your Cabal file in the :pkg-field:`library:signatures` field.
3356+
3357+
.. code-block:: haskell
3358+
:caption: .hsig
3359+
3360+
signature Str where
3361+
3362+
data Str
3363+
3364+
concat :: [Str] -> Str
3365+
3366+
.. code-block:: cabal
3367+
:caption: parametrized.cabal
3368+
3369+
cabal-version: 2.2
3370+
name: parametrized
3371+
3372+
library
3373+
build-depends: base
3374+
signatures: Str
3375+
exposed-modules: MyModule
3376+
3377+
You can define any number of regular modules (e.g., ``MyModule``) that
3378+
import signatures and use them as regular modules.
3379+
3380+
If you are familiar with ML modules, you might now expect there to be
3381+
some way to apply the parametrized package with an implementation of
3382+
the ``Str`` module to get a concrete instantiation of the package.
3383+
Backpack operates slightly differently with a concept of *mix-in
3384+
linking*, where you provide an implementation of ``Str`` simply by
3385+
bringing another module into scope with the same name as the
3386+
requirement. For example, if you had a package ``str-impl`` that provided a
3387+
module named ``Str``, instantiating ``parametrized`` is as simple as
3388+
just depending on both ``str-impl`` and ``parametrized``:
3389+
3390+
.. code-block:: cabal
3391+
:caption: combined.cabal
3392+
3393+
cabal-version: 2.2
3394+
name: combined
3395+
3396+
library
3397+
build-depends: base, str-impl, parametrized
3398+
3399+
Note that due to technical limmitations, you cannot directly define
3400+
``Str`` in the ``combined`` library; it must be placed in its own
3401+
library (you can use :ref:`Internal Libraries <sublibs>` to conveniently
3402+
define a sub-library).
3403+
3404+
However, a more common situation is that your names don't match up
3405+
exactly. The :pkg-field:`library:mixins` field can be used to rename
3406+
signatures and modules to line up names as necessary. If you have
3407+
a requirement ``Str`` and an implementation ``Data.Text``, you can
3408+
line up the names in one of two ways:
3409+
3410+
* Rename the requirement to match the implementation:
3411+
``mixins: parametrized requires (Str as Data.Text)``
3412+
* Rename the implementation to match the requirement:
3413+
``mixins: text (Data.Text as Str)``
3414+
3415+
The :pkg-field:`library:mixins` field can also be used to disambiguate
3416+
between multiple instantiations of the same package; for each
3417+
instantiation of the package, give it a separate entry in mixins with
3418+
the requirements and provided modules renamed to be distinct.
3419+
3420+
.. code-block:: cabal
3421+
:caption: .cabal
3422+
3423+
cabal-version: 2.2
3424+
name: double-combined
3425+
3426+
library
3427+
build-depends: base, text, bytestring, parametrized
3428+
mixins:
3429+
parametrized (MyModule as MyModule.Text) requires (Str as Data.Text),
3430+
parametrized (MyModule as MyModule.BS) requires (Str as Data.ByteString)
3431+
3432+
Intensive use of Backpack sometimes involves creating lots of small
3433+
parametrized libraries; :ref:`Internal Libraries <sublibs>` can be used
3434+
to define all of these libraries in a single package without having to
3435+
create many separate Cabal packages. You may also find it useful to use
3436+
:pkg-field:`library:reexported-modules` to reexport instantiated
3437+
libraries to Backpack-unware users (e.g., Backpack can be used entirely
3438+
as an implementation detail.)
3439+
3440+
For more information about Backpack, check out the
3441+
`GHC wiki page <https://gitlab.haskell.org/ghc/ghc/-/wikis/backpack>`__.
33363442
33373443
.. include:: references.inc
33383444

doc/references.inc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,3 @@
2222
.. _cpphs: http://projects.haskell.org/cpphs/
2323

2424
.. _ABNF: https://tools.ietf.org/html/rfc5234
25-
26-
.. _Backpack: https://gitlab.haskell.org/ghc/ghc/-/wikis/backpack

0 commit comments

Comments
 (0)