There is not yet a manual entry in Cabal for how Cabal works. This section is under development.
Edward Z. Yang's thesis contains detailed information about the specification and implementation of Backpack. We also have an older paper draft which was submitted to ICFP'16. History nuts can also read the original POPL paper but note that Backpack has changed dramatically since then.
You might find it useful to find some code using Backpack. Here are the biggest examples worth looking at:
unpacked-containers supplies unpacked sets and maps, using Backpack's ability to unpack through signatures.
backpack-str defines a signature and implementations for strings. It is quite comprehensive.
coda parametrizes over a few core data types including notions of "delta". It takes advantage of zero-cost abstraction, which lets it split into multiple data types, while still ensuring they are UNPACKed in the end.
streamy defines a signature and implementations for "streaming" libraries (e.g., conduit, pipes and streaming).
haskell-opentracing defines a signature for the OpenTracing standard, a middleware built on top of this signature, and (at the moment) a single backend to Jaeger.
reflex-backpack is a kind of crazy experiment at Backpack'ing Reflex. Reflex uses a lot of advanced GHC features and it took some coaxing to get Backpack to handle it all, but handle it all it did!
Some more out-of-date documents:
Backpack specification. This was subsumed by my thesis but once Backpack stabilizes it will be worth distilling the thesis PDF back into a more web-friendly format.
Can I use this with Stack? No, Backpack requires support from the package manager, and Stack integration has not been implemented yet.
This looks like it should work, but actually it will fail:
Error: Non-library component has unfilled requirements: StrImpl In the stanza 'library' In the inplace package 'mypkg-1.2'
The reason for this is Backpack does not (currently) support instantiating a package with a locally defined module: since the module can turn around and *import* the mixed in foo-indef, which would result in mutual recursion (not presently supported.)
To solve this problem, just create a new library to define the implementing module. This library can be in the same package using the convenience library mechanism:
How can I declare that a module implements a signature? In traditional Haskell style, you can write x :: Type to specify that a value x should have some type. In Backpack, specifying that a module implements a signature is done out-of-line; you must create a third component to link them together (e.g., a test suite):
If you need to specify that a module implements multiple signatures, you include all of those signatures in the same implements test or create separate implements tests.
Being a test suite, this requires you to create a dummy Main.hs file (main = return () is sufficient) and add a base dependency. So why do we pick a test suite? A test suite will ensure that you have in fact filled all of the holes of a foo-sig, whereas a regular library will happily pass through any unfilled holes, making it easy for you to think that a check has occurred when it has not.
You might wonder if you can skip defining an extra test-suite by mixing in the signature package from the implementation package. Unfortunately, this runs afoul the "you can't instantiate a dependency with a local module" restriction. Additionally, this adds an extra spurious dependency to your package which is not actually needed.
Backpack-related tickets are marked with label backpack. If the ticket is assigned to @ezyang, it means he's planning on working on it.