diff --git a/doc/buildinfo-fields-reference.rst b/doc/buildinfo-fields-reference.rst index 910bcf6813c..9deea2ba4d3 100644 --- a/doc/buildinfo-fields-reference.rst +++ b/doc/buildinfo-fields-reference.rst @@ -504,7 +504,7 @@ pkgconfig-depends virtual-modules * Monoidal field * Available since ``cabal-version: 2.2``. - * Documentation of :pkg-field:`virtual-modules` + * Documentation of :pkg-field:`library:virtual-modules` .. math:: \mathrm{commalist}\left({\left(\mathop{\mathit{upper}}{\left\{ \mathop{\mathit{alpha\text{-}num}}\mid[\mathop{\mathord{``}\mathtt{\text{'}}\mathord{"}}\mathop{\mathord{``}\mathtt{\text{_}}\mathord{"}}] \right\}}^\ast_{}\right)}^+_{\mathop{\mathord{``}\mathtt{\text{.}}\mathord{"}}}\right) diff --git a/doc/cabal-package-description-file.rst b/doc/cabal-package-description-file.rst index 485389a0916..10cd6e51704 100644 --- a/doc/cabal-package-description-file.rst +++ b/doc/cabal-package-description-file.rst @@ -890,7 +890,7 @@ The library section should contain the following fields: Supported only in GHC 8.2 and later. A list of `module signatures `__ required by this package. - Module signatures are part of the Backpack_ extension to + Module signatures are part of the :ref:`Backpack` extension to the Haskell module system. Packages that do not export any modules and only export required signatures @@ -2211,7 +2211,7 @@ system-dependent values for these fields. See the :pkg-field:`library:signatures` field for more details. - Mixin packages are part of the Backpack_ extension to the + Mixin packages are part of the :ref:`Backpack` extension to the Haskell module system. The matching of the module signatures required by a @@ -2224,7 +2224,7 @@ system-dependent values for these fields. .. Warning:: - Backpack_ has the limitation that implementation modules that instantiate + :ref:`Backpack` has the limitation that implementation modules that instantiate signatures required by a :pkg-field:`build-depends` dependency can't reside in the same component that has the dependency. They must reside in a different package dependency, or at least in a separate internal @@ -2923,16 +2923,6 @@ Right now :pkg-field:`executable:main-is` modules are not supported on (e.g. by a ``configure`` script). Autogenerated header files are not packaged by ``sdist`` command. -Virtual modules ---------------- - -TBW - -.. pkg-field:: virtual-modules: module list - :since: 2.2 - - TBW - .. _accessing-data-files: @@ -3305,123 +3295,6 @@ a few options: library for all or part of the work. One option is to copy the source of ``Distribution.Simple``, and alter it for your needs. Good luck. -.. _Backpack: - -Backpack --------- - -Cabal and GHC jointly support Backpack, an extension to Haskell's module -system which makes it possible to parametrize a package over some -modules, which can be instantiated later arbitrarily by a user. This -means you can write a library to be agnostic over some data -representation, and then instantiate it several times with different -data representations. Like C++ templates, instantiated packages are -recompiled for each instantiation, which means you do not pay any -runtime cost for parametrizing packages in this way. Backpack modules -are somewhat experimental; while fully supported by cabal-install, they are currently -`not supported by Stack `__. - -A Backpack package is defined by use of the -:pkg-field:`library:signatures` field, or by (transitive) dependency on -a package that defines some requirements. To define a parametrized -package, define a signature file (file extension ``hsig``) that -specifies the signature of the module you want to parametrize over, and -add it to your Cabal file in the :pkg-field:`library:signatures` field. - -.. code-block:: haskell - :caption: .hsig - - signature Str where - - data Str - - concat :: [Str] -> Str - -.. code-block:: cabal - :caption: parametrized.cabal - - cabal-version: 2.2 - name: parametrized - - library - build-depends: base - signatures: Str - exposed-modules: MyModule - -You can define any number of regular modules (e.g., ``MyModule``) that -import signatures and use them as regular modules. - -If you are familiar with ML modules, you might now expect there to be -some way to apply the parametrized package with an implementation of -the ``Str`` module to get a concrete instantiation of the package. -Backpack operates slightly differently with a concept of *mix-in -linking*, where you provide an implementation of ``Str`` simply by -bringing another module into scope with the same name as the -requirement. For example, if you had a package ``str-impl`` that provided a -module named ``Str``, instantiating ``parametrized`` is as simple as -just depending on both ``str-impl`` and ``parametrized``: - -.. code-block:: cabal - :caption: combined.cabal - - cabal-version: 2.2 - name: combined - - library - build-depends: base, str-impl, parametrized - -Note that due to technical limitations, you cannot directly define -``Str`` in the ``combined`` library; it must be placed in its own -library (you can use :ref:`Sublibraries ` to conveniently -define a sub-library). - -However, a more common situation is that your names don't match up -exactly. The :pkg-field:`library:mixins` field can be used to rename -signatures and modules to line up names as necessary. If you have -a requirement ``Str`` and an implementation ``Data.Text``, you can -line up the names in one of two ways: - -* Rename the requirement to match the implementation: - ``mixins: parametrized requires (Str as Data.Text)`` -* Rename the implementation to match the requirement: - ``mixins: text (Data.Text as Str)`` - -The :pkg-field:`library:mixins` field can also be used to disambiguate -between multiple instantiations of the same package; for each -instantiation of the package, give it a separate entry in mixins with -the requirements and provided modules renamed to be distinct. - -.. code-block:: cabal - :caption: .cabal - - cabal-version: 2.2 - name: double-combined - - library - build-depends: base, text, bytestring, parametrized - mixins: - parametrized (MyModule as MyModule.Text) requires (Str as Data.Text), - parametrized (MyModule as MyModule.BS) requires (Str as Data.ByteString) - -Intensive use of Backpack sometimes involves creating lots of small -parametrized libraries; :ref:`Sublibraries ` can be used -to define all of these libraries in a single package without having to -create many separate Cabal packages. You may also find it useful to use -:pkg-field:`library:reexported-modules` to reexport instantiated -libraries to Backpack-unware users (e.g., Backpack can be used entirely -as an implementation detail.) - -Backpack imposes a limitation on Template Haskell that goes beyond the usual TH -stage restriction: it's not possible to splice TH code imported from a -compilation unit that is still "indefinite", that is, a unit for which some -module signatures still haven't been matched with implementations. The reason -is that indefinite units are typechecked, but not compiled, so there's no -actual TH code to run while splicing. Splicing TH code from a definite -compilation unit into an indefinite one works normally. - -For more information about Backpack, check out the -`GHC wiki page `__. - .. include:: references.inc .. rubric:: Footnotes diff --git a/doc/how-to-use-backpack.rst b/doc/how-to-use-backpack.rst new file mode 100644 index 00000000000..23d58298b2d --- /dev/null +++ b/doc/how-to-use-backpack.rst @@ -0,0 +1,117 @@ +.. _Backpack: + +How to use Backpack modules +=========================== + +Cabal and GHC jointly support Backpack, an extension to Haskell's module +system which makes it possible to parametrize a package over some +modules, which can be instantiated later arbitrarily by a user. This +means you can write a library to be agnostic over some data +representation, and then instantiate it several times with different +data representations. Like C++ templates, instantiated packages are +recompiled for each instantiation, which means you do not pay any +runtime cost for parametrizing packages in this way. Backpack modules +are somewhat experimental; while fully supported by cabal-install, they are currently +`not supported by Stack `__. + +A Backpack package is defined by use of the +:pkg-field:`library:signatures` field, or by (transitive) dependency on +a package that defines some requirements. To define a parametrized +package, define a signature file (file extension ``hsig``) that +specifies the signature of the module you want to parametrize over, and +add it to your Cabal file in the :pkg-field:`library:signatures` field. + +.. code-block:: haskell + :caption: .hsig + + signature Str where + + data Str + + concat :: [Str] -> Str + +.. code-block:: cabal + :caption: parametrized.cabal + + cabal-version: 2.2 + name: parametrized + + library + build-depends: base + signatures: Str + exposed-modules: MyModule + +You can define any number of regular modules (e.g., ``MyModule``) that +import signatures and use them as regular modules. + +If you are familiar with ML modules, you might now expect there to be +some way to apply the parametrized package with an implementation of +the ``Str`` module to get a concrete instantiation of the package. +Backpack operates slightly differently with a concept of *mix-in +linking*, where you provide an implementation of ``Str`` simply by +bringing another module into scope with the same name as the +requirement. For example, if you had a package ``str-impl`` that provided a +module named ``Str``, instantiating ``parametrized`` is as simple as +just depending on both ``str-impl`` and ``parametrized``: + +.. code-block:: cabal + :caption: combined.cabal + + cabal-version: 2.2 + name: combined + + library + build-depends: base, str-impl, parametrized + +Note that due to technical limitations, you cannot directly define +``Str`` in the ``combined`` library; it must be placed in its own +library (you can use :ref:`Sublibraries ` to conveniently +define a sub-library). + +However, a more common situation is that your names don't match up +exactly. The :pkg-field:`library:mixins` field can be used to rename +signatures and modules to line up names as necessary. If you have +a requirement ``Str`` and an implementation ``Data.Text``, you can +line up the names in one of two ways: + +* Rename the requirement to match the implementation: + ``mixins: parametrized requires (Str as Data.Text)`` +* Rename the implementation to match the requirement: + ``mixins: text (Data.Text as Str)`` + +The :pkg-field:`library:mixins` field can also be used to disambiguate +between multiple instantiations of the same package; for each +instantiation of the package, give it a separate entry in mixins with +the requirements and provided modules renamed to be distinct. + +.. code-block:: cabal + :caption: .cabal + + cabal-version: 2.2 + name: double-combined + + library + build-depends: base, text, bytestring, parametrized + mixins: + parametrized (MyModule as MyModule.Text) requires (Str as Data.Text), + parametrized (MyModule as MyModule.BS) requires (Str as Data.ByteString) + +Intensive use of Backpack sometimes involves creating lots of small +parametrized libraries; :ref:`Sublibraries ` can be used +to define all of these libraries in a single package without having to +create many separate Cabal packages. You may also find it useful to use +:pkg-field:`library:reexported-modules` to reexport instantiated +libraries to Backpack-unware users (e.g., Backpack can be used entirely +as an implementation detail.) + +Backpack imposes a limitation on Template Haskell that goes beyond the usual TH +stage restriction: it's not possible to splice TH code imported from a +compilation unit that is still "indefinite", that is, a unit for which some +module signatures still haven't been matched with implementations. The reason +is that indefinite units are typechecked, but not compiled, so there's no +actual TH code to run while splicing. Splicing TH code from a definite +compilation unit into an indefinite one works normally. + +For more information about Backpack, check out the +`GHC wiki page `__. + diff --git a/doc/index.rst b/doc/index.rst index ed882247ea7..69109a67685 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -15,6 +15,7 @@ Welcome to the Cabal User Guide how-to-package-haskell-code how-to-build-like-nix + how-to-use-backpack how-to-report-bugs .. toctree::