Personal tools

Upgrading packages/Updating to GHC 6.10

From HaskellWiki

< Upgrading packages(Difference between revisions)
Jump to: navigation, search
m (fromJust -> fromMaybe)
(I think arrow's a subclass of cat, not a superclass... hope I'm not missing something here)

Revision as of 16:53, 14 October 2008

A list of things that need updating when porting packages to newer library/cabal versions.

If you maintain a Haskell package this is for you. For older versions of this document:

Updating to GHC 6.10 and Cabal 1.6

When upgrading to GHC 6.10, any of your packages that worked against the base-3 library will continue to work (unless you define instances of the Arrow class: see below). GHC 6.10 provides both the old base-3 library and the new base-4.

To ensure your old code continues to work, you can have the code compile and link against base-3, and then, over time, migrate code to the base-4 series.


1 Adding base-3 constraints

How to do this depends on how you build your Haskell code. We'll start with the most simplistic build mechanisms. cabal-install, the most sophisticated tool, will sort this all out for you anyway, so things should change.

1.1 ghc --make

Force use of package base-3 when using --make,

   ghc --make -package base-

1.2 runhaskell

If you build your packages with the 'runhaskell Setup.hs configure' method, then you can force the use of base-3,


1.3 cabal-install

It is worth upgrading cabal-install immediately (maybe before installing GHC). This way you can use the smart dependency solver to work out what to install for you.

* install HTTP from hackage
* install zlib from hackage

Then build cabal-install.

You can also override the dependencies when using the 'cabal' binary, with


2 Typical breakages with GHC 6.10

48 new packages break with the current GHC 6.10 release candidate.

The primary reasons are:

  • Changes to the Arrow class definition break Arrow instances
  • Changes to the return types of Map and Set functions
  • Cabal changes
  • Changes to ghc-api
  • Changes to when 'forall' is parsed
  • GHC.Prim was moved,
  • Changes to -fvia-C and headers
  • GADT changes,
  • pragma warnings tightened
  • Integer constructors have moved
  • New warnings and used -Werror

Each of these has a standard way to solve the problem. Techniques should be attached here.

2.1 Arrow instances

The relevant change is essentially that Arrow became a subclass of Category. To be exact:

  • (.) is a new function, in Category. (>>>) was removed from Arrow and made a function.
  • id is a new function, in Category

The base-3 compatibility package contains the same classes as base-4, so it will not save you if you define instances of the Arrow class: you'll need to change your code. Whenever you define an instance of Arrow you must also define an instance of Category, as follows:

  • Add the following imports:
    import Control.Category
    import Prelude hiding (id,(.)) -- conflicts with Category otherwise
  • Add instance Category [your type] where for any Arrow instances you define.
  • Move your (>>>) definition into Category, and change f >>> g = ... into g . f = ...
  • Define id in Category. The simplest definition is
    id = arr id
but you may wish to manually specialize this for efficiency.

And you're done.

2.2 Return types of Map and Set functions

Functions with signatures like

lookup :: (Monad m, Ord k) => k -> Map k a -> m a

have been specialized to

lookup :: (Ord k) => k -> Map k a -> Maybe a

If you assume the more specific type, your code will work with both old and new versions of the containers package. The brute force approach is to change each lookup k m to

fromMaybe (fail "lookup: key not found") $
  lookup k m

but you could also consider how you want to handle possible failures, or at least give a more informative error message.

2.3 Exception handling changes

The exception system was generalised in GHC 6.10, but GHC 6.10 still provides base-3, so all your applications can continue to work.

Follow the steps for compiling against base-3 at the top of the page, based on your build system.

Note that if you use cabal-install, it is smart enough to work this out for you.

2.4 Changes to -fvia-C and headers

GHC 6.10 no longer includes extra header files when compiling with -fvia-C. This makes compilation with -fvia-C consistent with the native code generator.

As a consequence, defining inline functions in header files and relying on -fvia-C to pick them up no longer works.

  • If you use a library that provides inline functions that you want to use, you will have to create wrapper functions to use them via FFI.
  • If you use the #def feature of hsc2hs, you can no longer define inline functions. That is, replace #def inline void foobar() { ... } by just #def void foobar() { ... }

The problem typically manifests itself as link errors (for example "ghc26356_0.hc:(.text+0x20282): undefined reference to `hs_curses_color_pair'").

Beware: In some cases, a library using inline functions will be built successfully, but programs using the library will fail to build.

3 Backwards compatibility

The new, suggested Cabal version range syntax,

  build-depends: base-3.*

is not backwards compatible with older versions of Cabal. Users will need to upgrade to the newer Cabal to build packages that start using this syntax.

4 GHC API changes

For converting a package that uses GHC-API, see [GhcApiStatus] for notes on the changes to the API and its use in 6.10. There are four main changes:

  • add imports 'MonadUtils' and 'SrcLoc'
  • use of 'runGhc' instead of newSession
  • code using getSession and related, converts to become monadic within Ghcmonad
  • String type becomes Located String type. To convert basic strings, use "L noSrcSpan <string>"