diff --git a/CHANGES b/CHANGES
deleted file mode 100644
--- a/CHANGES
+++ /dev/null
@@ -1,172 +0,0 @@
-3.8.7.4
-  Re-export runWithFuel as per Justin Bailey
-
-3.8.7.3
-  Uploaded to Hackage by Ian Lynagh; appears to contain updates
-  that use Safe Haskell if GHC >= 7.2 (thanks David Terei)
-
-3.8.7.2
-  Version changed with no record of update; never uploaded to Hackage
-
-3.8.7.1
-  Eliminate warning about nonexhaustive pattern match (thanks Edward Yang)
-
-3.8.7.0
-  Works with GHC 7 (thanks Edward Yang)
-  cabal sdist now sort of works (and is added to validate)
-
-3.8.6.0
-  Matches the camera-ready Haskell'10 paper
-
-3.8.1.0
-
-  Major reorganization per simonpj visit to Tufts 20 April 2010
-  Collections
-
-3.7.13.1
-
-  Added function to fold over nodes in graph.
-
-3.7.13.0
-
-  Pointed type replaces WithTop and WithBot, which are now synonyms.
-  
-
-3.7.12.3
-
-  Updates to Hoopl in the last week
-  =================================
-
-
-  Interface changes
-  -----------------
-  The type of AGraph is now abstract.
-  It is now recommended to create AGraphs with just three functions:
-
-    <*>          concatenation
-    |*><*|       splicing at a closed point
-    addBlocks    add C/C blocks out of line
-
-  There are new utility functions in modules Util and XUtil, all
-  exported by Compiler.Hoopl.  Here's a selection:
-
-    -- | A utility function so that a transfer function for a first
-    -- node can be given just a fact; we handle the lookup.  This
-    -- function is planned to be made obsolete by changes in the dataflow
-    -- interface.
-    firstXfer :: Edges n => (n C O -> f -> f) -> (n C O -> FactBase f -> f)
-    firstXfer xfer n fb = xfer n $ fromJust $ lookupFact fb $ entryLabel n
-    
-    -- | This utility function handles a common case in which a transfer function
-    -- produces a single fact out of a last node, which is then distributed
-    -- over the outgoing edges.
-    distributeXfer :: Edges n => (n O C -> f -> f) -> (n O C -> f -> FactBase f)
-    distributeXfer xfer n f = mkFactBase [ (l, xfer n f) | l <- successors n ]
-    
-    -- | This utility function handles a common case in which a transfer function
-    -- for a last node takes the incoming fact unchanged and simply distributes
-    -- that fact over the outgoing edges.
-    distributeFact :: Edges n => n O C -> f -> FactBase f
-
-    -- | Function 'graphMapBlocks' enables a change of representation of blocks,
-    -- nodes, or both.  It lifts a polymorphic block transform into a polymorphic
-    -- graph transform.  When the block representation stabilizes, a similar
-    -- function should be provided for blocks.
-    graphMapBlocks :: forall block n block' n' e x .
-                      (forall e x . block n e x -> block' n' e x)
-                   -> (Graph' block n e x -> Graph' block' n' e x)
-
-    postorder_dfs :: Edges (block n) => Graph' block n O x -> [block n C C]
-
-  There are quite a few other variations related to depth-first traversal.
-
-
-  There is a new module Compiler.Hoopl.Pointed, which uses GADTs to
-  enable you to add a Top or Bot element to a lattice, or both, all
-  using the same type.  (Types 'WithBot' and 'WithTop' in XUtil,
-  exported by Compiler.Hoopl, do similar jobs, but I think they are
-  inferior.  Your opinion is solicited.)
-
-  I added a function showGraph to print Graphs.  Right now it requires a
-  polymorphic node-showing function as argument. When we change the
-  Block representation we may get enough static type information that we
-  can simply have an instance declaration for 
-
-    instance (Show n C O, Show n O O, Show n O C) => Show (Graph n e x)
-
-  At present, I don't see how to achieve such a declaration.
-
-
-  John added new functions 'debugFwdJoins' and 'debugBwdJoins' to extend
-  passes with debugging information.
-
-  We added primed versions of the analyzeAndRewrite functions, which
-  operate on Graph, not Body.  Recommended, at least for first-timers.
-
-  Not all maps keyed by Label are FactBases, so there is now a new set
-  of names of functions to manipulate LabelMaps that do not contain
-  dataflow facts.
-
-
-
-  Implementation changes
-  ----------------------
-  Split pass and rewrite-function combinators into Compiler.Hoopl.Combinators.
-
-  Changed order of blocks for forward and backward analysis.
-  These changes have not been tested, because we don't have a true
-  regression suite yet.
-
-  Graph and Body types now have more polymorphic variants Graph' and Body'.
-
-  Lots of experiments with zippers.
-
-
-
-  Changes ahead
-  -------------
-  ForwardTransfer will become an abstract type, and clients will have
-  two ways to create ForwardTransfers: as now, with a single,
-  polymorphic transfer function; or with a triple of monomorphic
-  transfer functions.  The implementation will use monomorphic
-  functions, which will enable more useful combinators on passes,
-  including adding more debugging information and enabling us to combine
-  passes. 
-
-  Perhaps we should provide splicing and 'addBlocks' on Graph?
-
-  Change of block representation to have three monomorphic unit
-  constructors and one polymorphic concatenation constructor.
-
-  Graph body to be represented by a finite map; add functions to check
-  for duplicate labels.
-
-3.7.12.1
-
-  - Added a bunch of zipper experiments.
-  - Existing clients should not be affected.
-
-
-3.7.12.0
-
-  - More expressive debugging support
-  - retract arfGraph and normalization; export analyzeAndRewriterFwd'
-
-3.7.11.1
-
-  - Expose arfGraph and normalization functions
-
-3.7.11.0
-
-  - Debugging support
-
-3.7.8.0
-
-  - Rationalized AGraph splicing functions.
-
-3.7.7.0
-
-  - Restrict clients so they see much less, including hiding
-    the value constructors for Body.
-
-
diff --git a/FAQ b/FAQ
deleted file mode 100644
--- a/FAQ
+++ /dev/null
diff --git a/changelog.md b/changelog.md
new file mode 100644
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,278 @@
+# Changelog for [`hoopl` package](http://hackage.haskell.org/package/hoopl)
+
+## 3.10.0.0  *Mar 2014*
+
+  - Bundled with GHC 7.8.1
+
+  - Define `Functor` and `Applicative` instances for
+     - `SimpleUniqueMonad`
+     - `CheckingFuelMonad`
+     - `InfiniteFuelMonad`
+     - `UniqueMonadT`
+     - `VM` (not exported)
+
+  - Update to Cabal format 1.10
+
+## 3.9.0.0
+
+Lots of API changes; mainly a new API for working with Blocks
+
+### Summary of refactorings:
+
+   - `Compiler.Hoopl.Block` contains the `Block` datatype and all the
+     operations on Blocks.  It seemed like a good idea to collect all
+     this stuff together in one place.
+
+   - `Compiler.Hoopl.Graph` now has the operations on Graphs.
+
+   - `Compiler.Hoopl.Util` and `Compiler.Hoopl.GraphUtil` are no more; their
+     contents have been moved to other homes.  (and a bit of duplicated
+     functionality has been removed).
+
+   - I removed the newtypes around `Unique` and `Label`, these are now just
+     type synonyms.  The newtype wrappers were costing some performance in
+     GHC, because in cases like `mapToList` the newtype isn't optimised away.
+
+     This change might be controversial.  Feel free to complain.
+
+### Other changes:
+
+   - Optimisations to the Dataflow algorithms.  I'm not actually using
+     this implementation of Dataflow in GHC any more, instead I have a
+     local copy specialised to our monad, for speed.  Nevertheless I've
+     put some of the optimisations I'm using in the GHC version into the
+     generic library version too.
+
+### Summary of API changes:
+
+#### Added
+
+  - `IsMap(mapInsertWith, mapFromListWith)`
+
+  - `mapGraphBlocks`
+    (was previously called `graphMapBlocks`, and not exported)
+
+  - `mapBlock'`
+    (strict version of `mapBlock`)
+
+  - New API for working with Blocks:
+
+    ```haskell
+      -- ** Predicates on Blocks
+    , isEmptyBlock
+ 
+      -- ** Constructing blocks
+    , emptyBlock, blockCons, blockSnoc
+    , blockJoinHead, blockJoinTail, blockJoin, blockJoinAny
+    , blockAppend
+ 
+      -- ** Deconstructing blocks
+    , firstNode, lastNode, endNodes
+    , blockSplitHead, blockSplitTail, blockSplit, blockSplitAny
+ 
+      -- ** Modifying blocks
+    , replaceFirstNode, replaceLastNode
+ 
+      -- ** Converting to and from lists
+    , blockToList, blockFromList
+ 
+      -- ** Maps and folds
+    , mapBlock, mapBlock', mapBlock3'
+    , foldBlockNodesF, foldBlockNodesF3
+    , foldBlockNodesB, foldBlockNodesB3
+    ```
+
+#### Removed
+
+  - `mapMaybeO`, `mapMaybeC`
+    (no need: we have `Functor` instances)
+
+  - Block constructors are no longer exported
+    (use the block API instead)
+
+  - `blockToNodeList`, `blockToNodeList'`, `blockToNodeList''`, `blockToNodeList'''`
+    (use the block API instead)
+
+  - `tfFoldBlock`, `ScottBlock`, `scottFoldBlock`, `fbnf3`,
+    `BlockResult(..)`, `lookupBlock`,
+    (I don't know what any of these are for, if they're still important
+    we could reinstate)
+
+#### Changed
+
+  - Compiler.Hoopl.GHC is now Compiler.Hoopl.Internals and exports some
+    more stuff.
+
+  - Label is not a newtype; type Label = Unique
+  - Unique is not a newtype: type Unique = Int
+    (these newtypes were adding overhead)
+
+  - blockMapNodes3 is now mapBlock3'
+
+  - Lots of internal refactoring and tidying up
+
+## 3.8.7.4
+
+  - Re-export runWithFuel as per Justin Bailey
+
+## 3.8.7.3
+
+  - Uploaded to Hackage by Ian Lynagh; appears to contain updates
+    that use Safe Haskell if GHC >= 7.2 (thanks David Terei)
+
+## 3.8.7.2
+
+  - Version changed with no record of update; never uploaded to Hackage
+
+## 3.8.7.1
+
+  - Eliminate warning about nonexhaustive pattern match (thanks Edward Yang)
+
+## 3.8.7.0
+
+  - Works with GHC 7 (thanks Edward Yang)
+  - `cabal sdist` now sort of works (and is added to validate)
+
+## 3.8.6.0
+
+  - Matches the camera-ready Haskell'10 paper
+
+## 3.8.1.0
+
+  - Major reorganization per simonpj visit to Tufts 20 April 2010
+    Collections
+
+## 3.7.13.1
+
+  - Added function to fold over nodes in graph.
+
+## 3.7.13.0
+
+  - Pointed type replaces WithTop and WithBot, which are now synonyms.
+
+## 3.7.12.3
+
+### Interface changes
+
+The type of AGraph is now abstract.
+It is now recommended to create AGraphs with just three functions:
+
+    <*>          concatenation
+    |*><*|       splicing at a closed point
+    addBlocks    add C/C blocks out of line
+
+There are new utility functions in modules Util and XUtil, all
+exported by Compiler.Hoopl.  Here's a selection:
+
+    -- | A utility function so that a transfer function for a first
+    -- node can be given just a fact; we handle the lookup.  This
+    -- function is planned to be made obsolete by changes in the dataflow
+    -- interface.
+    firstXfer :: Edges n => (n C O -> f -> f) -> (n C O -> FactBase f -> f)
+    firstXfer xfer n fb = xfer n $ fromJust $ lookupFact fb $ entryLabel n
+
+    -- | This utility function handles a common case in which a transfer function
+    -- produces a single fact out of a last node, which is then distributed
+    -- over the outgoing edges.
+    distributeXfer :: Edges n => (n O C -> f -> f) -> (n O C -> f -> FactBase f)
+    distributeXfer xfer n f = mkFactBase [ (l, xfer n f) | l <- successors n ]
+
+    -- | This utility function handles a common case in which a transfer function
+    -- for a last node takes the incoming fact unchanged and simply distributes
+    -- that fact over the outgoing edges.
+    distributeFact :: Edges n => n O C -> f -> FactBase f
+
+    -- | Function 'graphMapBlocks' enables a change of representation of blocks,
+    -- nodes, or both.  It lifts a polymorphic block transform into a polymorphic
+    -- graph transform.  When the block representation stabilizes, a similar
+    -- function should be provided for blocks.
+    graphMapBlocks :: forall block n block' n' e x .
+                      (forall e x . block n e x -> block' n' e x)
+                   -> (Graph' block n e x -> Graph' block' n' e x)
+
+    postorder_dfs :: Edges (block n) => Graph' block n O x -> [block n C C]
+
+There are quite a few other variations related to depth-first traversal.
+
+
+There is a new module Compiler.Hoopl.Pointed, which uses GADTs to
+enable you to add a Top or Bot element to a lattice, or both, all
+using the same type.  (Types `WithBot` and `WithTop` in XUtil,
+exported by Compiler.Hoopl, do similar jobs, but I think they are
+inferior.  Your opinion is solicited.)
+
+I added a function showGraph to print Graphs.  Right now it requires a
+polymorphic node-showing function as argument. When we change the
+Block representation we may get enough static type information that we
+can simply have an instance declaration for
+
+    instance (Show n C O, Show n O O, Show n O C) => Show (Graph n e x)
+
+At present, I don't see how to achieve such a declaration.
+
+John added new functions `debugFwdJoins` and `debugBwdJoins` to extend
+passes with debugging information.
+
+We added primed versions of the analyzeAndRewrite functions, which
+operate on Graph, not Body.  Recommended, at least for first-timers.
+
+Not all maps keyed by Label are FactBases, so there is now a new set
+of names of functions to manipulate LabelMaps that do not contain
+dataflow facts.
+
+### Implementation changes
+
+Split pass and rewrite-function combinators into Compiler.Hoopl.Combinators.
+
+Changed order of blocks for forward and backward analysis.
+These changes have not been tested, because we don't have a true
+regression suite yet.
+
+Graph and Body types now have more polymorphic variants Graph' and Body'.
+
+Lots of experiments with zippers.
+
+### Changes ahead
+
+ForwardTransfer will become an abstract type, and clients will have
+two ways to create ForwardTransfers: as now, with a single,
+polymorphic transfer function; or with a triple of monomorphic
+transfer functions.  The implementation will use monomorphic
+functions, which will enable more useful combinators on passes,
+including adding more debugging information and enabling us to combine
+passes.
+
+Perhaps we should provide splicing and `addBlocks` on Graph?
+
+Change of block representation to have three monomorphic unit
+constructors and one polymorphic concatenation constructor.
+
+Graph body to be represented by a finite map; add functions to check
+for duplicate labels.
+
+## 3.7.12.1
+
+  - Added a bunch of zipper experiments.
+  - Existing clients should not be affected.
+
+## 3.7.12.0
+
+  - More expressive debugging support
+  - retract arfGraph and normalization; export analyzeAndRewriterFwd'
+
+## 3.7.11.1
+
+  - Expose arfGraph and normalization functions
+
+## 3.7.11.0
+
+  - Debugging support
+
+## 3.7.8.0
+
+  - Rationalized AGraph splicing functions.
+
+## 3.7.7.0
+
+  - Restrict clients so they see much less, including hiding
+    the value constructors for Body.
diff --git a/hoopl.cabal b/hoopl.cabal
--- a/hoopl.cabal
+++ b/hoopl.cabal
@@ -1,5 +1,7 @@
 Name:                hoopl
-Version:             3.9.0.0
+Version:             3.10.0.0
+-- NOTE: Don't forget to update 'repository this' tag when incrementing version!
+-- GHC 7.6.1 released with 3.9.0.0
 -- version 3.8.6.0 is the version that goes with the camera-ready Haskell'10 paper
 -- version 3.8.7.0 works with GHC 7
 -- version 3.8.7.1 adds some unnamed functions without breaking compatibility
@@ -9,24 +11,48 @@
 Description:
   Higher-order optimization library
   .
-  Changes in 3.9.0.0
-  .
-  * Lots of API changes; mainly a new API for working with Blocks
+  See /Norman Ramsey, João Dias, and Simon Peyton Jones./
+  <http://research.microsoft.com/en-us/um/people/simonpj/Papers/c--/hoopl-haskell10.pdf "Hoopl: A Modular, Reusable Library for Dataflow Analysis and Transformation"> /(2010)/ for more details.
 
 License:             BSD3
 License-File:        LICENSE
 Author:              Norman Ramsey, João Dias, Simon Marlow and Simon Peyton Jones
 Maintainer:          nr@cs.tufts.edu
 Homepage:            http://ghc.cs.tufts.edu/hoopl/
+Bug-Reports:         http://ghc.haskell.org/trac/ghc/newticket?component=libraries/hoopl
 Build-Type:          Simple
-Cabal-Version:       >=1.6
+Cabal-Version:       >=1.10
 Synopsis:            A library to support dataflow analysis and optimization
 Category:            Compilers/Interpreters
-Extra-Source-Files:  README, hoopl.pdf, CHANGES, FAQ
+Tested-With:         GHC==7.6.3, GHC==7.6.2, GHC==7.6.1, GHC==7.4.2, GHC==7.4.1, GHC==7.2.2, GHC==7.0.4, GHC==7.0.3, GHC==7.0.2, GHC==7.0.1
+Extra-Source-Files:  README, hoopl.pdf, changelog.md
 
+Source-repository head
+  Type:       git
+  Location:   http://git.haskell.org/packages/hoopl.git
+
+Source-repository this
+  Type:       git
+  Location:   http://git.haskell.org/packages/hoopl.git
+  Tag:        hoopl-3.10.0.0-release
+
 Library
+  Default-Language:  Haskell2010
+  Other-Extensions:  CPP
+                     FlexibleContexts
+                     FlexibleInstances
+                     GADTs
+                     LiberalTypeSynonyms
+                     MultiParamTypeClasses
+                     RankNTypes
+                     ScopedTypeVariables
+                     TypeFamilies
+                     TypeSynonymInstances
+  If impl(ghc>=7.2)
+    Other-Extensions: Safe Trustworthy
+
   Hs-Source-Dirs:    src
-  Build-Depends:     base >= 3 && < 5, containers
+  Build-Depends:     base >= 4.3 && < 4.8, containers >= 0.4 && < 0.6
   Exposed-Modules:   Compiler.Hoopl,
                      Compiler.Hoopl.Internals,
                      Compiler.Hoopl.Wrappers,
@@ -48,13 +74,9 @@
                      Compiler.Hoopl.Fuel,
                      Compiler.Hoopl.Pointed,
                      Compiler.Hoopl.Shape,
-                     Compiler.Hoopl.Show, 
-                     Compiler.Hoopl.Unique, 
+                     Compiler.Hoopl.Show,
+                     Compiler.Hoopl.Unique,
                      Compiler.Hoopl.XUtil
 
   Ghc-Options:       -Wall -fno-warn-name-shadowing
-  Extensions:        CPP
 
-Source-repository head
-  Type:       git
-  Location:   git://ghc.cs.tufts.edu/hoopl/hoopl.git
diff --git a/src/Compiler/Hoopl.hs b/src/Compiler/Hoopl.hs
--- a/src/Compiler/Hoopl.hs
+++ b/src/Compiler/Hoopl.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Safe #-}
 #endif
diff --git a/src/Compiler/Hoopl/Block.hs b/src/Compiler/Hoopl/Block.hs
--- a/src/Compiler/Hoopl/Block.hs
+++ b/src/Compiler/Hoopl/Block.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE GADTs, EmptyDataDecls, TypeFamilies, ScopedTypeVariables, RankNTypes #-}
+{-# LANGUAGE CPP, GADTs, TypeFamilies, ScopedTypeVariables, RankNTypes #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Safe #-}
 #endif
@@ -125,8 +125,8 @@
 
 blockCons :: n O O -> Block n O x -> Block n O x
 blockCons n b = case b of
-  BlockOC b l  -> BlockOC (n `BCons` b) l
-  BNil{}    -> n `BCons` b
+  BlockOC b l  -> (BlockOC $! (n `blockCons` b)) l
+  BNil{}    -> BMiddle n
   BMiddle{} -> n `BCons` b
   BCat{}    -> n `BCons` b
   BSnoc{}   -> n `BCons` b
@@ -134,8 +134,8 @@
 
 blockSnoc :: Block n e O -> n O O -> Block n e O
 blockSnoc b n = case b of
-  BlockCO f b -> BlockCO f (b `BSnoc` n)
-  BNil{}      -> b `BSnoc` n
+  BlockCO f b -> BlockCO f $! (b `blockSnoc` n)
+  BNil{}      -> BMiddle n
   BMiddle{}   -> b `BSnoc` n
   BCat{}      -> b `BSnoc` n
   BSnoc{}     -> b `BSnoc` n
diff --git a/src/Compiler/Hoopl/Checkpoint.hs b/src/Compiler/Hoopl/Checkpoint.hs
--- a/src/Compiler/Hoopl/Checkpoint.hs
+++ b/src/Compiler/Hoopl/Checkpoint.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE CPP, TypeFamilies #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Safe #-}
 #endif
diff --git a/src/Compiler/Hoopl/Collections.hs b/src/Compiler/Hoopl/Collections.hs
--- a/src/Compiler/Hoopl/Collections.hs
+++ b/src/Compiler/Hoopl/Collections.hs
@@ -1,6 +1,6 @@
 {- Baseclasses for Map-like and Set-like collections inspired by containers. -}
 
-{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE CPP, TypeFamilies #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Safe #-}
 #endif
@@ -72,6 +72,7 @@
   mapMapWithKey :: (KeyOf map -> a -> b) -> map a -> map b
   mapFold :: (a -> b -> b) -> b -> map a -> b
   mapFoldWithKey :: (KeyOf map -> a -> b -> b) -> b -> map a -> b
+  mapFilter :: (a -> Bool) -> map a -> map a
 
   mapElems :: map a -> [a]
   mapKeys :: map a -> [KeyOf map]
diff --git a/src/Compiler/Hoopl/Combinators.hs b/src/Compiler/Hoopl/Combinators.hs
--- a/src/Compiler/Hoopl/Combinators.hs
+++ b/src/Compiler/Hoopl/Combinators.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE RankNTypes, LiberalTypeSynonyms, ScopedTypeVariables, GADTs #-}
+{-# LANGUAGE CPP, RankNTypes, LiberalTypeSynonyms, ScopedTypeVariables, GADTs #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Safe #-}
 #endif
diff --git a/src/Compiler/Hoopl/Dataflow.hs b/src/Compiler/Hoopl/Dataflow.hs
--- a/src/Compiler/Hoopl/Dataflow.hs
+++ b/src/Compiler/Hoopl/Dataflow.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE RankNTypes, ScopedTypeVariables, GADTs, EmptyDataDecls, PatternGuards, TypeFamilies, MultiParamTypeClasses #-}
+{-# LANGUAGE CPP, RankNTypes, ScopedTypeVariables, GADTs, TypeFamilies, MultiParamTypeClasses #-}
 #if __GLASGOW_HASKELL__ >= 703
 {- OPTIONS_GHC -fprof-auto #-}
 #endif
diff --git a/src/Compiler/Hoopl/Debug.hs b/src/Compiler/Hoopl/Debug.hs
--- a/src/Compiler/Hoopl/Debug.hs
+++ b/src/Compiler/Hoopl/Debug.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE RankNTypes, GADTs, ScopedTypeVariables, FlexibleContexts #-}
+{-# LANGUAGE CPP, RankNTypes, GADTs, ScopedTypeVariables, FlexibleContexts #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Safe #-}
 #endif
diff --git a/src/Compiler/Hoopl/Fuel.hs b/src/Compiler/Hoopl/Fuel.hs
--- a/src/Compiler/Hoopl/Fuel.hs
+++ b/src/Compiler/Hoopl/Fuel.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE CPP, TypeFamilies #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Safe #-}
 #endif
@@ -21,6 +21,9 @@
 import Compiler.Hoopl.Checkpoint
 import Compiler.Hoopl.Unique
 
+import Control.Applicative (Applicative(..))
+import Control.Monad (ap,liftM)
+
 class Monad m => FuelMonad m where
   getFuel :: m Fuel
   setFuel :: Fuel -> m ()
@@ -50,6 +53,13 @@
 
 newtype CheckingFuelMonad m a = FM { unFM :: Fuel -> m (a, Fuel) }
 
+instance Monad m => Functor (CheckingFuelMonad m) where
+  fmap  = liftM
+
+instance Monad m => Applicative (CheckingFuelMonad m) where
+  pure  = return
+  (<*>) = ap
+
 instance Monad m => Monad (CheckingFuelMonad m) where
   return a = FM (\f -> return (a, f))
   fm >>= k = FM (\f -> do { (a, f') <- unFM fm f; unFM (k a) f' })
@@ -74,6 +84,14 @@
 ----------------------------------------------------------------
 
 newtype InfiniteFuelMonad m a = IFM { unIFM :: m a }
+
+instance Monad m => Functor (InfiniteFuelMonad m) where
+  fmap  = liftM
+
+instance Monad m => Applicative (InfiniteFuelMonad m) where
+  pure  = return
+  (<*>) = ap
+
 instance Monad m => Monad (InfiniteFuelMonad m) where
   return a = IFM $ return a
   m >>= k  = IFM $ do { a <- unIFM m; unIFM (k a) }
diff --git a/src/Compiler/Hoopl/Graph.hs b/src/Compiler/Hoopl/Graph.hs
--- a/src/Compiler/Hoopl/Graph.hs
+++ b/src/Compiler/Hoopl/Graph.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE GADTs, EmptyDataDecls, TypeFamilies, ScopedTypeVariables,
+{-# LANGUAGE CPP, GADTs, TypeFamilies, ScopedTypeVariables,
     RankNTypes, FlexibleInstances, TypeSynonymInstances #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Safe #-}
@@ -46,8 +46,8 @@
 import Compiler.Hoopl.Block
 import Compiler.Hoopl.Label
 
-import Control.Monad
-
+import Control.Applicative (Applicative(..))
+import Control.Monad (ap,liftM,liftM2)
 
 -- -----------------------------------------------------------------------------
 -- Body
@@ -348,12 +348,22 @@
 ----------------------------------------------------------------
 
 data VM a = VM { unVM :: LabelSet -> (a, LabelSet) }
-marked :: Label -> VM Bool
-mark   :: Label -> VM ()
+
+instance Functor VM where
+  fmap  = liftM
+
+instance Applicative VM where
+  pure  = return
+  (<*>) = ap
+
 instance Monad VM where
   return a = VM $ \visited -> (a, visited)
   m >>= k  = VM $ \visited -> let (a, v') = unVM m visited in unVM (k a) v'
+
+marked :: Label -> VM Bool
 marked l = VM $ \v -> (setMember l v, v)
+
+mark   :: Label -> VM ()
 mark   l = VM $ \v -> ((), setInsert l v)
 
 preorder_dfs_from_except :: forall block e . (NonLocal block, LabelsPtr e)
diff --git a/src/Compiler/Hoopl/Internals.hs b/src/Compiler/Hoopl/Internals.hs
--- a/src/Compiler/Hoopl/Internals.hs
+++ b/src/Compiler/Hoopl/Internals.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE GADTs, RankNTypes #-}
+{-# LANGUAGE CPP, GADTs, RankNTypes #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Safe #-}
 #endif
diff --git a/src/Compiler/Hoopl/Label.hs b/src/Compiler/Hoopl/Label.hs
--- a/src/Compiler/Hoopl/Label.hs
+++ b/src/Compiler/Hoopl/Label.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE CPP, TypeFamilies #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Safe #-}
 #endif
@@ -91,6 +91,7 @@
   mapMapWithKey f (LM m) = LM (mapMapWithKey (f . uniqueToLbl) m)
   mapFold k z (LM m) = mapFold k z m
   mapFoldWithKey k z (LM m) = mapFoldWithKey (k . uniqueToLbl) z m
+  mapFilter f (LM m) = LM (mapFilter f m)
 
   mapElems (LM m) = mapElems m
   mapKeys (LM m) = map uniqueToLbl (mapKeys m)
diff --git a/src/Compiler/Hoopl/MkGraph.hs b/src/Compiler/Hoopl/MkGraph.hs
--- a/src/Compiler/Hoopl/MkGraph.hs
+++ b/src/Compiler/Hoopl/MkGraph.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ScopedTypeVariables, GADTs, TypeSynonymInstances, FlexibleInstances, RankNTypes #-}
+{-# LANGUAGE CPP, ScopedTypeVariables, GADTs, TypeSynonymInstances, FlexibleInstances, RankNTypes #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Safe #-}
 #endif
@@ -18,7 +18,9 @@
 import Compiler.Hoopl.Block
 import Compiler.Hoopl.Graph as U
 import Compiler.Hoopl.Unique
-import Control.Monad (liftM2)
+
+import Control.Monad (Monad(..),liftM2)
+import Prelude (($),(.),foldr,map) -- for the purpose of 'hiding ((<*>))'
 
 {-|
 As noted in the paper, we can define a single, polymorphic type of 
diff --git a/src/Compiler/Hoopl/Passes/DList.hs b/src/Compiler/Hoopl/Passes/DList.hs
--- a/src/Compiler/Hoopl/Passes/DList.hs
+++ b/src/Compiler/Hoopl/Passes/DList.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE GADTs #-}
+{-# LANGUAGE CPP, GADTs #-}
 {-# OPTIONS_GHC -Wall -fno-warn-name-shadowing #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Safe #-}
diff --git a/src/Compiler/Hoopl/Passes/Dominator.hs b/src/Compiler/Hoopl/Passes/Dominator.hs
--- a/src/Compiler/Hoopl/Passes/Dominator.hs
+++ b/src/Compiler/Hoopl/Passes/Dominator.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE GADTs #-}
+{-# LANGUAGE CPP, GADTs #-}
 {-# OPTIONS_GHC -Wall -fno-warn-name-shadowing #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Safe #-}
diff --git a/src/Compiler/Hoopl/Pointed.hs b/src/Compiler/Hoopl/Pointed.hs
--- a/src/Compiler/Hoopl/Pointed.hs
+++ b/src/Compiler/Hoopl/Pointed.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE GADTs, ScopedTypeVariables #-}
+{-# LANGUAGE CPP, GADTs, ScopedTypeVariables #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Safe #-}
 #endif
diff --git a/src/Compiler/Hoopl/Shape.hs b/src/Compiler/Hoopl/Shape.hs
--- a/src/Compiler/Hoopl/Shape.hs
+++ b/src/Compiler/Hoopl/Shape.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE GADTs, EmptyDataDecls #-}
+{-# LANGUAGE CPP, GADTs #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Safe #-}
 #endif
diff --git a/src/Compiler/Hoopl/Show.hs b/src/Compiler/Hoopl/Show.hs
--- a/src/Compiler/Hoopl/Show.hs
+++ b/src/Compiler/Hoopl/Show.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE RankNTypes, GADTs, ScopedTypeVariables, FlexibleContexts #-}
+{-# LANGUAGE CPP, RankNTypes, GADTs, ScopedTypeVariables, FlexibleContexts #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Safe #-}
 #endif
diff --git a/src/Compiler/Hoopl/Unique.hs b/src/Compiler/Hoopl/Unique.hs
--- a/src/Compiler/Hoopl/Unique.hs
+++ b/src/Compiler/Hoopl/Unique.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE CPP, TypeFamilies #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Trustworthy #-}
 #endif
@@ -21,6 +21,9 @@
 import qualified Data.IntMap as M
 import qualified Data.IntSet as S
 
+import Control.Applicative (Applicative(..))
+import Control.Monad (ap,liftM)
+
 -----------------------------------------------------------------------------
 --		Unique
 -----------------------------------------------------------------------------
@@ -90,6 +93,7 @@
   mapMapWithKey f (UM m) = UM (M.mapWithKey (f . intToUnique) m)
   mapFold k z (UM m) = M.fold k z m
   mapFoldWithKey k z (UM m) = M.foldWithKey (k . intToUnique) z m
+  mapFilter f (UM m) = UM (M.filter f m)
 
   mapElems (UM m) = M.elems m
   mapKeys (UM m) = M.keys m
@@ -105,6 +109,13 @@
 
 newtype SimpleUniqueMonad a = SUM { unSUM :: [Unique] -> (a, [Unique]) }
 
+instance Functor SimpleUniqueMonad where
+  fmap = liftM
+
+instance Applicative SimpleUniqueMonad where
+  pure  = return
+  (<*>) = ap
+
 instance Monad SimpleUniqueMonad where
   return a = SUM $ \us -> (a, us)
   m >>= k  = SUM $ \us -> let (a, us') = unSUM m us in
@@ -126,6 +137,13 @@
 ----------------------------------------------------------------
 
 newtype UniqueMonadT m a = UMT { unUMT :: [Unique] -> m (a, [Unique]) }
+
+instance Monad m => Functor (UniqueMonadT m) where
+  fmap  = liftM
+
+instance Monad m => Applicative (UniqueMonadT m) where
+  pure  = return
+  (<*>) = ap
 
 instance Monad m => Monad (UniqueMonadT m) where
   return a = UMT $ \us -> return (a, us)
diff --git a/src/Compiler/Hoopl/Wrappers.hs b/src/Compiler/Hoopl/Wrappers.hs
--- a/src/Compiler/Hoopl/Wrappers.hs
+++ b/src/Compiler/Hoopl/Wrappers.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Safe #-}
 #endif
diff --git a/src/Compiler/Hoopl/XUtil.hs b/src/Compiler/Hoopl/XUtil.hs
--- a/src/Compiler/Hoopl/XUtil.hs
+++ b/src/Compiler/Hoopl/XUtil.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE GADTs, RankNTypes, ScopedTypeVariables, TypeFamilies  #-}
+{-# LANGUAGE CPP, GADTs, RankNTypes, ScopedTypeVariables, TypeFamilies  #-}
 #if __GLASGOW_HASKELL__ >= 701
 {-# LANGUAGE Trustworthy #-}
 #endif
