This is the launch page for Backpack, actively maintained by Edward (as of Aug 2017).

Backpack is a system for retrofitting Haskell with an applicative, mix-in module system. It has been implemented in GHC 8.2 and cabal-install 2.0, but it is not supported by Stack.

The documentation for how to use Backpack is a bit scattered about at this point, but here are useful, up-to-date (as of 2017-04-02, prior to GHC 8.2's release) references:

  • This pair of blog posts: Try Backpack, ghc --backpack and Cabal packages have up-to-date tutorials for using the main features of Backpack, with and without Cabal.
  • 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.
  • Hackage does not yet support uploads of Backpack-using packages. next.hackage is a Hackage instances running a development branch of Hackage that can handle Backpack; for now, Backpack-enabled packages should be uploaded here.

You might find it useful to find some code using Backpack. Here are the biggest examples worth looking at:

  • backpack-str defines a signature and implementations for strings. It is quite comprehensive, and the packages are available on next.hackage.
  • 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.
  • slay is a layouting engine parametrized over Double and Int coordinate types.
  • 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.

Known gotchas

Can I use this with Stack? No, Backpack requires support from the package manager, and Stack integration has not been implemented yet.

Make sure cabal-version is recent enough. (#4448) If you set the cabal-version of your package too low, you may get this error:

    Mix-in refers to non-existent package 'pkg'
    (did you forget to add the package to build-depends?)
    In the stanza 'executable myexe'
    In the inplace package 'pkg'

This is because internal libraries are feature-gated by the cabal-version of your package. Setting it to cabal-version: >= 2.0 is enough to resolve the problem.

You can't instantiate a dependency with a locally defined module. Consider the following package:

  other-modules: StrImpl
  build-depends: foo-indef
  mixins: foo-indef requires (Str as StrImpl)

This looks like it should work, but actually it will fail:

    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:

library str-impl
  exposed-modules: StrImpl

  build-depends: str-impl, foo-indef
  mixins: foo-indef requires (Str as StrImpl)

Backpack-related tickets

Backpack-related tickets are marked with keyword 'backpack'. If the ticket is assigned to ezyang, it means he's planning on working on it.

Ticket Type Summary Priority Owner
#1409 feature request Allow recursively dependent modules transparently (without .hs-boot or anything) normal
#9351 feature request add ability to version symbols .c for packages with C code normal
#10749 bug Boot file instances should imply superclasses normal ezyang
#10827 feature request GHCi should support interpeting multiple packages/units with separate DynFlags normal
#12703 feature request Expand Backpack's signature matching relation beyond definitional equality normal
#13151 task Make all never-exported IfaceDecls implicit normal ezyang
#13266 bug Source locations from signature merging/matching are bad normal
#13469 feature request -fdefer-type-errors for Backpack normal
#14212 bug Give better error message with non-supported Backpack/TH use normal
#10266 task Split base for Backpack low ezyang
#10681 feature request Teach GHC to interpret all hs files as two levels of hs-boot files (abstract types only/full types + values) low ezyang
#12680 feature request Permit type equality instances in signatures low
#13149 task Giving Backpack a Promotion low
#13262 feature request Allow type synonym family application in instance head if it has no free variables low
#13361 bug Better type synonym merging/subtyping for Backpack low
#13765 bug GHC cannot parse valid Haskell98 whose first identifier is named signature low
#14210 feature request bkp files cannot find TemplateHaskell symbols (even without Backpack features) low
#10871 feature request Implement "fat" interface files which can be directly compiled without source lowest ezyang
#12717 feature request Permit data types in signatures to be implemented with equivalent pattern synonyms (and vice versa) lowest

Last modified 10 days ago Last modified on Oct 11, 2017 2:45:24 AM