diff --git a/hindent.cabal b/hindent.cabal
--- a/hindent.cabal
+++ b/hindent.cabal
@@ -1,5 +1,5 @@
 name:                hindent
-version:             4.2.4
+version:             4.3.0
 synopsis:            Extensible Haskell pretty printer
 description:         Extensible Haskell pretty printer. Both a library and an executable.
                      .
diff --git a/src/HIndent.hs b/src/HIndent.hs
--- a/src/HIndent.hs
+++ b/src/HIndent.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE OverloadedStrings, TupleSections, ScopedTypeVariables #-}
 
 -- | Haskell indenter.
@@ -62,12 +63,12 @@
     ParseFailed _ e -> Left e
 
 -- | Pretty print the given printable thing.
-prettyPrint :: Style -> Printer () -> Builder
+prettyPrint :: Style -> (forall s. Printer s ()) -> Builder
 prettyPrint style m =
-  psOutput (execState (runPrinter m)
-                      (case style of
-                         Style _name _author _desc st extenders config ->
-                           PrintState 0 mempty False 0 1 st extenders config False False))
+  case style of
+    Style _name _author _desc st extenders config ->
+      psOutput (execState (runPrinter m)
+                          (PrintState 0 mempty False 0 1 st extenders config False False))
 
 -- | Parse mode, includes all extensions, doesn't assume any fixities.
 parseMode :: ParseMode
diff --git a/src/HIndent/Pretty.hs b/src/HIndent/Pretty.hs
--- a/src/HIndent/Pretty.hs
+++ b/src/HIndent/Pretty.hs
@@ -13,6 +13,10 @@
     Pretty
   , pretty
   , prettyNoExt
+  -- * User state
+  ,getState
+  ,putState
+  ,modifyState
   -- * Insertion
   , write
   , newline
@@ -80,10 +84,10 @@
 
 -- | Pretty printing class.
 class (Annotated ast,Typeable ast) => Pretty ast where
-  prettyInternal :: MonadState PrintState m => ast NodeInfo -> m ()
+  prettyInternal :: MonadState (PrintState s) m => ast NodeInfo -> m ()
 
 -- | Pretty print using extenders.
-pretty :: (Pretty ast,MonadState PrintState m)
+pretty :: (Pretty ast,MonadState (PrintState s) m)
        => ast NodeInfo -> m ()
 pretty a =
   do st <- get
@@ -98,19 +102,19 @@
              (printComments After a)
   where makePrinter s (Extender f) =
           case cast a of
-            Just v -> Just (f s v)
+            Just v -> Just (f v)
             Nothing -> Nothing
         makePrinter s (CatchAll f) = f s a
 
 -- | Run the basic printer for the given node without calling an
 -- extension hook for this node, but do allow extender hooks in child
 -- nodes. Also auto-inserts comments.
-prettyNoExt :: (Pretty ast,MonadState PrintState m)
+prettyNoExt :: (Pretty ast,MonadState (PrintState s) m)
             => ast NodeInfo -> m ()
 prettyNoExt = prettyInternal
 
 -- | Print comments of a node.
-printComments :: (Pretty ast,MonadState PrintState m)
+printComments :: (Pretty ast,MonadState (PrintState s) m)
               => ComInfoLocation -> ast NodeInfo -> m ()
 printComments loc' ast =
   forM_ comments $ \comment ->
@@ -124,7 +128,7 @@
         comments = nodeInfoComments info
 
 -- | Pretty print a comment.
-printComment :: MonadState PrintState m => Maybe SrcSpan -> ComInfo -> m ()
+printComment :: MonadState (PrintState s) m => Maybe SrcSpan -> ComInfo -> m ()
 printComment mayNodespan (ComInfo (Comment inline cspan str) _) =
   do -- Insert proper amount of space before comment.
      -- This maintains alignment. This cannot force comments
@@ -148,15 +152,27 @@
 
 -- | Pretty print using HSE's own printer. The 'P.Pretty' class here
 -- is HSE's.
-pretty' :: (Pretty ast,P.Pretty (ast SrcSpanInfo),Functor ast,MonadState PrintState m)
+pretty' :: (Pretty ast,P.Pretty (ast SrcSpanInfo),Functor ast,MonadState (PrintState s) m)
         => ast NodeInfo -> m ()
 pretty' = write . T.fromText . T.pack . P.prettyPrint . fmap nodeInfoSpan
 
 --------------------------------------------------------------------------------
 -- * Combinators
 
+-- | Get the user state.
+getState :: Printer s s
+getState = gets psUserState
+
+-- | Put the user state.
+putState :: s -> Printer s ()
+putState s' = modifyState (const s')
+
+-- | Modify the user state.
+modifyState :: (s -> s) -> Printer s ()
+modifyState f = modify (\s -> s {psUserState = f (psUserState s)})
+
 -- | Increase indentation level by n spaces for the given printer.
-indented :: MonadState PrintState m => Int64 -> m a -> m a
+indented :: MonadState (PrintState s) m => Int64 -> m a -> m a
 indented i p =
   do level <- gets psIndentLevel
      modify (\s -> s {psIndentLevel = level + i})
@@ -165,15 +181,15 @@
      return m
 
 -- | Print all the printers separated by spaces.
-spaced :: MonadState PrintState m => [m ()] -> m ()
+spaced :: MonadState (PrintState s) m => [m ()] -> m ()
 spaced = inter space
 
 -- | Print all the printers separated by commas.
-commas :: MonadState PrintState m => [m ()] -> m ()
+commas :: MonadState (PrintState s) m => [m ()] -> m ()
 commas = inter comma
 
 -- | Print all the printers separated by sep.
-inter :: MonadState PrintState m => m () -> [m ()] -> m ()
+inter :: MonadState (PrintState s) m => m () -> [m ()] -> m ()
 inter sep ps =
   foldr (\(i,p) next ->
            depend (do p
@@ -185,12 +201,12 @@
         (zip [1 ..] ps)
 
 -- | Print all the printers separated by newlines.
-lined :: MonadState PrintState m => [m ()] -> m ()
+lined :: MonadState (PrintState s) m => [m ()] -> m ()
 lined ps = sequence_ (intersperse newline ps)
 
 -- | Print all the printers separated newlines and optionally a line
 -- prefix.
-prefixedLined :: MonadState PrintState m => Text -> [m ()] -> m ()
+prefixedLined :: MonadState (PrintState s) m => Text -> [m ()] -> m ()
 prefixedLined pref ps' =
   case ps' of
     [] -> return ()
@@ -206,7 +222,7 @@
 
 -- | Set the (newline-) indent level to the given column for the given
 -- printer.
-column :: MonadState PrintState m => Int64 -> m a -> m a
+column :: MonadState (PrintState s) m => Int64 -> m a -> m a
 column i p =
   do level <- gets psIndentLevel
      modify (\s -> s {psIndentLevel = i})
@@ -215,21 +231,21 @@
      return m
 
 -- | Get the current indent level.
-getColumn :: MonadState PrintState m => m Int64
+getColumn :: MonadState (PrintState s) m => m Int64
 getColumn = gets psColumn
 
 -- | Get the current line number.
-getLineNum :: MonadState PrintState m => m Int64
+getLineNum :: MonadState (PrintState s) m => m Int64
 getLineNum = gets psLine
 
 -- | Output a newline.
-newline :: MonadState PrintState m => m ()
+newline :: MonadState (PrintState s) m => m ()
 newline =
   do write "\n"
      modify (\s -> s {psNewline = True})
 
 -- | Set the context to a case context, where RHS is printed with -> .
-withCaseContext :: MonadState PrintState m
+withCaseContext :: MonadState (PrintState s) m
                 => Bool -> m a -> m a
 withCaseContext bool pr =
   do original <- gets psInsideCase
@@ -239,7 +255,7 @@
      return result
 
 -- | Get the current RHS separator, either = or -> .
-rhsSeparator :: MonadState PrintState m
+rhsSeparator :: MonadState (PrintState s) m
              => m ()
 rhsSeparator =
   do inCase <- gets psInsideCase
@@ -249,7 +265,7 @@
 
 -- | Make the latter's indentation depend upon the end column of the
 -- former.
-depend :: MonadState PrintState m => m () -> m b -> m b
+depend :: MonadState (PrintState s) m => m () -> m b -> m b
 depend maker dependent =
   do state' <- get
      maker
@@ -261,7 +277,7 @@
 
 -- | Make the latter's indentation depend upon the end column of the
 -- former.
-dependBind :: MonadState PrintState m => m a -> (a -> m b) -> m b
+dependBind :: MonadState (PrintState s) m => m a -> (a -> m b) -> m b
 dependBind maker dependent =
   do state' <- get
      v <- maker
@@ -272,7 +288,7 @@
         else (dependent v)
 
 -- | Wrap in parens.
-parens :: MonadState PrintState m => m a -> m a
+parens :: MonadState (PrintState s) m => m a -> m a
 parens p =
   depend (write "(")
          (do v <- p
@@ -280,7 +296,7 @@
              return v)
 
 -- | Wrap in braces.
-braces :: MonadState PrintState m => m a -> m a
+braces :: MonadState (PrintState s) m => m a -> m a
 braces p =
   depend (write "{")
          (do v <- p
@@ -288,7 +304,7 @@
              return v)
 
 -- | Wrap in brackets.
-brackets :: MonadState PrintState m => m a -> m a
+brackets :: MonadState (PrintState s) m => m a -> m a
 brackets p =
   depend (write "[")
          (do v <- p
@@ -296,20 +312,20 @@
              return v)
 
 -- | Write a space.
-space :: MonadState PrintState m => m ()
+space :: MonadState (PrintState s) m => m ()
 space = write " "
 
 -- | Write a comma.
-comma :: MonadState PrintState m => m ()
+comma :: MonadState (PrintState s) m => m ()
 comma = write ","
 
 -- | Write an integral.
-int :: (Integral n, MonadState PrintState m)
+int :: (Integral n, MonadState (PrintState s) m)
     => n -> m ()
 int = write . decimal
 
 -- | Write out a string, updating the current position information.
-write :: MonadState PrintState m => Builder -> m ()
+write :: MonadState (PrintState s) m => Builder -> m ()
 write x =
   do eol <- gets psEolComment
      when (eol && x /= "\n") newline
@@ -341,16 +357,16 @@
           LT.length (LT.filter (== '\n') x')
 
 -- | Write a string.
-string :: MonadState PrintState m =>String -> m ()
+string :: MonadState (PrintState s) m =>String -> m ()
 string = write . T.fromText . T.pack
 
 -- | Indent spaces, e.g. 2.
-getIndentSpaces :: MonadState PrintState m => m Int64
+getIndentSpaces :: MonadState (PrintState s) m => m Int64
 getIndentSpaces =
   gets (configIndentSpaces . psConfig)
 
 -- | Column limit, e.g. 80
-getColumnLimit :: MonadState PrintState m => m Int64
+getColumnLimit :: MonadState (PrintState s) m => m Int64
 getColumnLimit =
   gets (configMaxColumns . psConfig)
 
@@ -371,7 +387,7 @@
 nullBinds (IPBinds _ x) = null x
 
 -- | Maybe render a class context.
-maybeCtx :: MonadState PrintState m => Maybe (Context NodeInfo) -> m ()
+maybeCtx :: MonadState (PrintState s) m => Maybe (Context NodeInfo) -> m ()
 maybeCtx =
   maybe (return ())
         (\p ->
@@ -379,7 +395,7 @@
            write " => ")
 
 -- | Maybe render an overlap definition.
-maybeOverlap :: MonadState PrintState m => Maybe (Overlap NodeInfo) -> m ()
+maybeOverlap :: MonadState (PrintState s) m => Maybe (Overlap NodeInfo) -> m ()
 maybeOverlap =
   maybe (return ())
         (\p ->
@@ -387,7 +403,7 @@
            space)
 
 -- | Swing the second printer below and indented with respect to the first.
-swing :: MonadState PrintState m => m () -> m b -> m b
+swing :: MonadState (PrintState s) m => m () -> m b -> m b
 swing a b =
   do orig <- gets psIndentLevel
      a
@@ -477,7 +493,7 @@
       PVar{} -> pretty' x
 
 -- | Pretty print a name for being an infix operator.
-prettyInfixOp :: MonadState PrintState m => QName NodeInfo -> m ()
+prettyInfixOp :: MonadState (PrintState s) m => QName NodeInfo -> m ()
 prettyInfixOp x =
   case x of
     Qual{} -> pretty' x
@@ -546,7 +562,7 @@
   prettyInternal = exp
 
 -- | Render an expression.
-exp :: MonadState PrintState m => Exp NodeInfo -> m ()
+exp :: MonadState (PrintState s) m => Exp NodeInfo -> m ()
 exp (InfixApp _ a op b) =
   depend (do pretty a
              space
@@ -756,7 +772,7 @@
   prettyInternal = decl
 
 -- | Render a declaration.
-decl :: MonadState PrintState m => Decl NodeInfo -> m ()
+decl :: MonadState (PrintState s) m => Decl NodeInfo -> m ()
 decl (PatBind _ pat rhs mbinds) =
   do pretty pat
      withCaseContext False (pretty rhs)
diff --git a/src/HIndent/Styles/ChrisDone.hs b/src/HIndent/Styles/ChrisDone.hs
--- a/src/HIndent/Styles/ChrisDone.hs
+++ b/src/HIndent/Styles/ChrisDone.hs
@@ -61,8 +61,8 @@
 --     -> (Char -> X -> Y)
 --     -> IO ()
 --
-decl :: t -> Decl NodeInfo -> Printer ()
-decl _ (TypeSig _ names ty') =
+decl :: Decl NodeInfo -> Printer s ()
+decl (TypeSig _ names ty') =
   depend (do inter (write ", ")
                    (map pretty names)
              write " :: ")
@@ -101,11 +101,11 @@
           do overflows <- isOverflow (pretty p)
              oneLine <- isSingleLiner (pretty p)
              return (not overflows && oneLine)
-decl _ e = prettyNoExt e
+decl e = prettyNoExt e
 
 -- | I want field updates to be dependent or newline.
-fieldupdate :: t -> FieldUpdate NodeInfo -> Printer ()
-fieldupdate _ e =
+fieldupdate :: FieldUpdate NodeInfo -> Printer t ()
+fieldupdate e =
   case e of
     FieldUpdate _ n e' ->
       dependOrNewline
@@ -116,44 +116,44 @@
     _ -> prettyNoExt e
 
 -- | Right-hand sides are dependent.
-rhs :: s -> Rhs NodeInfo -> Printer ()
-rhs s grhs =
+rhs :: Rhs NodeInfo -> Printer t ()
+rhs grhs =
   do inCase <- gets psInsideCase
      if inCase
-        then unguardedalt s grhs
-        else unguardedrhs s grhs
+        then unguardedalt grhs
+        else unguardedrhs grhs
 
 -- | Right-hand sides are dependent.
-unguardedrhs :: s -> Rhs NodeInfo -> Printer ()
-unguardedrhs _ (UnGuardedRhs _ e) =
+unguardedrhs :: Rhs NodeInfo -> Printer t ()
+unguardedrhs (UnGuardedRhs _ e) =
   do indentSpaces <- getIndentSpaces
      indented indentSpaces
               (dependOrNewline (write " = ")
                                e
                                pretty)
-unguardedrhs _ e = prettyNoExt e
+unguardedrhs e = prettyNoExt e
 
 -- | Unguarded case alts.
-unguardedalt :: t -> Rhs NodeInfo -> Printer ()
-unguardedalt _ (UnGuardedRhs _ e) =
+unguardedalt :: Rhs NodeInfo -> Printer t ()
+unguardedalt (UnGuardedRhs _ e) =
   dependOrNewline
     (write " -> ")
     e
     (indented 2 .
      pretty)
-unguardedalt _ e = prettyNoExt e
+unguardedalt e = prettyNoExt e
 
 -- | Decide whether to do alts or rhs based on the context.
-contextualGuardedRhs :: s -> GuardedRhs NodeInfo -> Printer ()
-contextualGuardedRhs s grhs =
+contextualGuardedRhs :: GuardedRhs NodeInfo -> Printer t ()
+contextualGuardedRhs grhs =
   do inCase <- gets psInsideCase
      if inCase
-        then guardedalt s grhs
-        else guardedrhs s grhs
+        then guardedalt grhs
+        else guardedrhs grhs
 
 -- | I want guarded RHS be dependent or newline.
-guardedrhs :: s -> GuardedRhs NodeInfo -> Printer ()
-guardedrhs _ (GuardedRhs _ stmts e) =
+guardedrhs :: GuardedRhs NodeInfo -> Printer t ()
+guardedrhs (GuardedRhs _ stmts e) =
   indented 1
            (do prefixedLined
                  ","
@@ -168,8 +168,8 @@
                   pretty))
 
 -- | I want guarded alts be dependent or newline.
-guardedalt :: s -> GuardedRhs NodeInfo -> Printer ()
-guardedalt _ (GuardedRhs _ stmts e) =
+guardedalt :: GuardedRhs NodeInfo -> Printer t ()
+guardedalt (GuardedRhs _ stmts e) =
   indented 1
            (do (prefixedLined
                   ","
@@ -187,12 +187,12 @@
 -- do x *
 --    y
 -- is two invalid statements, not one valid infix op.
-stmt :: s -> Stmt NodeInfo -> Printer ()
-stmt _ (Qualifier _ e@(InfixApp _ a op b)) =
+stmt :: Stmt NodeInfo -> Printer t ()
+stmt (Qualifier _ e@(InfixApp _ a op b)) =
   do col <- fmap (psColumn . snd)
                  (sandbox (write ""))
      infixApp e a op b (Just col)
-stmt _ (Generator _ p e) =
+stmt (Generator _ p e) =
   do indentSpaces <- getIndentSpaces
      pretty p
      indented indentSpaces
@@ -200,19 +200,19 @@
                  (write " <- ")
                  e
                  pretty)
-stmt _ e = prettyNoExt e
+stmt e = prettyNoExt e
 
 -- | Expressions
-exp :: s -> Exp NodeInfo -> Printer ()
+exp :: Exp NodeInfo -> Printer t ()
 -- Infix applications will render on one line if possible, otherwise
 -- if any of the arguments are not "flat" then that expression is
 -- line-separated.
-exp _ e@(InfixApp _ a op b) =
+exp e@(InfixApp _ a op b) =
   infixApp e a op b Nothing
 -- | We try to render everything on a flat line. More than one of the
 -- arguments are not flat and it wouldn't be a single liner.
 -- If the head is short we depend, otherwise we swing.
-exp _ (App _ op a) =
+exp (App _ op a) =
   do orig <- gets psIndentLevel
      dependBind
        (do (short,st) <- isShort f
@@ -239,7 +239,7 @@
           flatten f' (a' : b)
         flatten f' as = (f',as)
 -- | Lambdas are dependent if they can be.
-exp _ (Lambda _ ps b) =
+exp (Lambda _ ps b) =
   depend (write "\\")
          (do spaced (map pretty ps)
              dependOrNewline
@@ -247,7 +247,7 @@
                b
                (indented 1 .
                 pretty))
-exp _ (Tuple _ boxed exps) =
+exp (Tuple _ boxed exps) =
   depend (write (case boxed of
                    Unboxed -> "(#"
                    Boxed -> "("))
@@ -261,7 +261,7 @@
                       Unboxed -> "#)"
                       Boxed -> ")"))
   where p = commas (map pretty exps)
-exp _ (List _ es) =
+exp (List _ es) =
   do (ok,st) <- sandbox renderFlat
      if ok
         then put st
@@ -275,7 +275,7 @@
              let overflow = psColumn st > columnLimit
                  single = psLine st == line
              return (not overflow && single)
-exp _ e = prettyNoExt e
+exp e = prettyNoExt e
 
 --------------------------------------------------------------------------------
 -- Indentation helpers
@@ -283,7 +283,7 @@
 -- | Sandbox and render the nodes on multiple lines, returning whether
 -- each is a single line.
 sandboxSingles :: Pretty ast
-               => [ast NodeInfo] -> Printer (Bool,PrintState)
+               => [ast NodeInfo] -> Printer t (Bool,PrintState t)
 sandboxSingles args =
   sandbox (allM (\(i,arg) ->
                    do when (i /=
@@ -297,7 +297,7 @@
 
 -- | Render multi-line nodes.
 multi :: Pretty ast
-      => Int64 -> [ast NodeInfo] -> Bool -> Printer ()
+      => Int64 -> [ast NodeInfo] -> Bool -> Printer t ()
 multi orig args headIsShort =
   if headIsShort
      then lined (map pretty args)
@@ -312,7 +312,7 @@
 -- | Sandbox and render the node on a single line, return whether it's
 -- on a single line and whether it's overflowing.
 sandboxNonOverflowing :: Pretty ast
-                      => [ast NodeInfo] -> Printer ((Bool,Bool),PrintState)
+                      => [ast NodeInfo] -> Printer t ((Bool,Bool),PrintState t)
 sandboxNonOverflowing args =
   sandbox (do line <- gets psLine
               columnLimit <- getColumnLimit
@@ -327,7 +327,7 @@
 
 -- | Is the expression "short"? Used for app heads.
 isShort :: (Pretty ast)
-        => ast NodeInfo -> Printer (Bool,PrintState)
+        => ast NodeInfo -> Printer t (Bool,PrintState t)
 isShort p =
   do line <- gets psLine
      orig <- fmap (psColumn . snd)
@@ -339,8 +339,8 @@
 
 -- | Is the given expression "small"? I.e. does it fit on one line and
 -- under 'smallColumnLimit' columns.
-isSmall :: MonadState PrintState m
-        => m a -> m (Bool,PrintState)
+isSmall :: MonadState (PrintState t) m
+        => m a -> m (Bool,PrintState t)
 isSmall p =
   do line <- gets psLine
      (_,st) <- sandbox p
@@ -365,21 +365,21 @@
 isFlat _ = False
 
 -- | Does printing the given thing overflow column limit? (e.g. 80)
-isOverflow :: Printer a -> Printer Bool
+isOverflow :: Printer t a -> Printer t Bool
 isOverflow p =
   do (_,st) <- sandbox p
      columnLimit <- getColumnLimit
      return (psColumn st > columnLimit)
 
 -- | Does printing the given thing overflow column limit? (e.g. 80)
-isOverflowMax :: Printer a -> Printer Bool
+isOverflowMax :: Printer t a -> Printer t Bool
 isOverflowMax p =
   do (_,st) <- sandbox p
      columnLimit <- getColumnLimit
      return (psColumn st > columnLimit + 20)
 
 -- | Is the given expression a single-liner when printed?
-isSingleLiner :: MonadState PrintState m
+isSingleLiner :: MonadState (PrintState t) m
               => m a -> m Bool
 isSingleLiner p =
   do line <- gets psLine
@@ -395,7 +395,7 @@
          -> ast1 NodeInfo
          -> ast2 NodeInfo
          -> Maybe Int64
-         -> Printer ()
+         -> Printer t ()
 infixApp e a op b indent =
   do let is = isFlat e
      overflow <- isOverflow
@@ -423,10 +423,10 @@
 
 -- | Make the right hand side dependent if it's flat, otherwise
 -- newline it.
-dependOrNewline :: Printer ()
+dependOrNewline :: Printer t ()
                 -> Exp NodeInfo
-                -> (Exp NodeInfo -> Printer ())
-                -> Printer ()
+                -> (Exp NodeInfo -> Printer t ())
+                -> Printer t ()
 dependOrNewline left right f =
   do if isFlat right
         then renderDependent
diff --git a/src/HIndent/Styles/Gibiansky.hs b/src/HIndent/Styles/Gibiansky.hs
--- a/src/HIndent/Styles/Gibiansky.hs
+++ b/src/HIndent/Styles/Gibiansky.hs
@@ -53,7 +53,7 @@
 indentSpaces = 2
 
 -- | Printer to indent one level.
-indentOnce :: Printer ()
+indentOnce :: Printer s ()
 indentOnce = replicateM_ indentSpaces $ write " "
 
 -- | How many exports to format in a single line.
@@ -61,7 +61,7 @@
 maxSingleLineExports :: Integral a => a
 maxSingleLineExports = 4
 
-attemptSingleLine :: Printer a -> Printer a -> Printer a
+attemptSingleLine :: Printer s a -> Printer s a -> Printer s a
 attemptSingleLine single multiple = do
   -- Try printing on one line.
   prevState <- get
@@ -78,11 +78,11 @@
 
 --------------------------------------------------------------------------------
 -- Extenders
-type Extend f = forall t. t -> f NodeInfo -> Printer ()
+type Extend f = forall t. f NodeInfo -> Printer t ()
 
 -- | Format whole modules.
 modl :: Extend Module
-modl _ (Module _ mayModHead pragmas imps decls) = do
+modl (Module _ mayModHead pragmas imps decls) = do
   onSeparateLines pragmas
   unless (null pragmas) $
     unless (null imps && null decls && isNothing mayModHead) $
@@ -95,24 +95,24 @@
   onSeparateLines imps
   unless (null imps || null decls) (newline >> newline)
   onSeparateLines decls
-modl _ m = prettyNoExt m
+modl m = prettyNoExt m
 
 -- | Format pragmas differently (language pragmas).
 pragmas :: Extend ModulePragma
-pragmas _ (LanguagePragma _ names) = do
+pragmas (LanguagePragma _ names) = do
   write "{-# LANGUAGE "
   inter (write ", ") $ map pretty names
   write " #-}"
-pragmas _ p = prettyNoExt p
+pragmas p = prettyNoExt p
 
 -- | Format patterns.
 pat :: Extend Pat
-pat _ (PTuple _ boxed pats) = writeTuple boxed pats
-pat _ p = prettyNoExt p
+pat (PTuple _ boxed pats) = writeTuple boxed pats
+pat p = prettyNoExt p
 
 -- | Format import statements.
 imp :: Extend ImportDecl
-imp _ ImportDecl{..} = do
+imp ImportDecl{..} = do
   write "import "
   write $ if importQualified
             then "qualified "
@@ -129,13 +129,13 @@
 
 -- | Format contexts with spaces and commas between class constraints.
 context :: Extend Context
-context _ (CxTuple _ asserts) =
+context (CxTuple _ asserts) =
   parens $ inter (comma >> space) $ map pretty asserts
-context _ ctx = prettyNoExt ctx
+context ctx = prettyNoExt ctx
 
 -- | Format deriving clauses with spaces and commas between class constraints.
 derivings :: Extend Deriving
-derivings _ (Deriving _ instHeads) = do
+derivings (Deriving _ instHeads) = do
   write "deriving "
   go instHeads
 
@@ -149,7 +149,7 @@
 -- For contexts, check whether the context and all following function types
 -- are on the same line. If they are, print them on the same line; otherwise
 -- print the context and each argument to the function on separate lines.
-typ _ (TyForall _ _ (Just ctx) rest) =
+typ (TyForall _ _ (Just ctx) rest) =
   if all (sameLine ctx) $ collectTypes rest
     then do
       pretty ctx
@@ -162,8 +162,8 @@
         newline
         write "=> "
         indented 3 $ pretty rest
-typ _ (TyTuple _ boxed types) = writeTuple boxed types
-typ _ ty@(TyFun _ from to) =
+typ (TyTuple _ boxed types) = writeTuple boxed types
+typ ty@(TyFun _ from to) =
   -- If the function argument types are on the same line,
   -- put the entire function type on the same line.
   if all (sameLine from) $ collectTypes ty
@@ -171,7 +171,7 @@
       pretty from
       write " -> "
       pretty to
-    else 
+    else
     -- If the function argument types are on different lines,
     -- write one argument type per line.
     do
@@ -181,9 +181,9 @@
         newline
         write "-> "
         indented 3 $ pretty to
-typ _ t = prettyNoExt t
+typ t = prettyNoExt t
 
-writeTuple :: Pretty ast => Boxed -> [ast NodeInfo] -> Printer ()
+writeTuple :: Pretty ast => Boxed -> [ast NodeInfo] -> Printer s ()
 writeTuple boxed vals = parens $ do
   boxed'
   inter (write ", ") $ map pretty vals
@@ -205,23 +205,23 @@
 collectTypes ty = [ty]
 
 exprs :: Extend Exp
-exprs _ exp@Let{} = letExpr exp
-exprs _ exp@App{} = appExpr exp
-exprs _ exp@Do{} = doExpr exp
-exprs _ exp@List{} = listExpr exp
-exprs _ exp@(InfixApp _ _ (QVarOp _ (UnQual _ (Symbol _ "$"))) _) = dollarExpr exp
-exprs _ exp@(InfixApp _ _ (QVarOp _ (UnQual _ (Symbol _ "<*>"))) _) = applicativeExpr exp
-exprs _ exp@InfixApp{} = opExpr exp
-exprs _ exp@Lambda{} = lambdaExpr exp
-exprs _ exp@Case{} = caseExpr exp
-exprs _ exp@LCase{} = lambdaCaseExpr exp
-exprs _ exp@If{} = ifExpr exp
-exprs _ (RecUpdate _ exp updates) = recUpdateExpr (pretty exp) updates
-exprs _ (RecConstr _ qname updates) = recUpdateExpr (pretty qname) updates
-exprs _ (Tuple _ _ exps) = parens $ inter (write ", ") $ map pretty exps
-exprs _ exp = prettyNoExt exp
+exprs exp@Let{} = letExpr exp
+exprs exp@App{} = appExpr exp
+exprs exp@Do{} = doExpr exp
+exprs exp@List{} = listExpr exp
+exprs exp@(InfixApp _ _ (QVarOp _ (UnQual _ (Symbol _ "$"))) _) = dollarExpr exp
+exprs exp@(InfixApp _ _ (QVarOp _ (UnQual _ (Symbol _ "<*>"))) _) = applicativeExpr exp
+exprs exp@InfixApp{} = opExpr exp
+exprs exp@Lambda{} = lambdaExpr exp
+exprs exp@Case{} = caseExpr exp
+exprs exp@LCase{} = lambdaCaseExpr exp
+exprs exp@If{} = ifExpr exp
+exprs (RecUpdate _ exp updates) = recUpdateExpr (pretty exp) updates
+exprs (RecConstr _ qname updates) = recUpdateExpr (pretty qname) updates
+exprs (Tuple _ _ exps) = parens $ inter (write ", ") $ map pretty exps
+exprs exp = prettyNoExt exp
 
-letExpr :: Exp NodeInfo -> Printer ()
+letExpr :: Exp NodeInfo -> Printer s ()
 letExpr (Let _ binds result) = do
   cols <- depend (write "let ") $ do
             col <- getColumn
@@ -233,7 +233,7 @@
     pretty result
 letExpr _ = error "Not a let"
 
-appExpr :: Exp NodeInfo -> Printer ()
+appExpr :: Exp NodeInfo -> Printer s ()
 appExpr app@(App _ f x) = do
   prevState <- get
   prevLine <- getLineNum
@@ -266,7 +266,7 @@
         indentOnce
         pretty x
 
-    canSingleLine :: Printer a -> Printer Bool
+    canSingleLine :: Printer s a -> Printer s Bool
     canSingleLine printer = do
       st <- get
       prevLine <- getLineNum
@@ -283,7 +283,7 @@
       in (fun, y : args)
     collectArgs nonApp = (nonApp, [])
 
-    separateArgs :: Exp NodeInfo -> Printer ()
+    separateArgs :: Exp NodeInfo -> Printer s ()
     separateArgs expr =
       let (fun, args) = collectArgs expr
       in do
@@ -294,24 +294,24 @@
           indented indentSpaces $ lined $ map pretty $ reverse args
 appExpr _ = error "Not an app"
 
-doExpr :: Exp NodeInfo -> Printer ()
+doExpr :: Exp NodeInfo -> Printer s ()
 doExpr (Do _ stmts) = do
   write "do"
   newline
   indented 2 $ onSeparateLines stmts
 doExpr _ = error "Not a do"
 
-listExpr :: Exp NodeInfo -> Printer ()
+listExpr :: Exp NodeInfo -> Printer s ()
 listExpr (List _ els) = attemptSingleLine (singleLineList els) (multiLineList els)
 listExpr _ = error "Not a list"
 
-singleLineList :: [Exp NodeInfo] -> Printer ()
+singleLineList :: [Exp NodeInfo] -> Printer s ()
 singleLineList exps = do
   write "["
   inter (write ", ") $ map pretty exps
   write "]"
 
-multiLineList :: [Exp NodeInfo] -> Printer ()
+multiLineList :: [Exp NodeInfo] -> Printer s ()
 multiLineList [] = write "[]"
 multiLineList (first:exps) = do
   col <- getColumn
@@ -326,7 +326,7 @@
     newline
     write "]"
 
-dollarExpr :: Exp NodeInfo -> Printer ()
+dollarExpr :: Exp NodeInfo -> Printer s ()
 dollarExpr (InfixApp _ left op right) = do
   pretty left
   write " "
@@ -344,14 +344,14 @@
     needsNewline exp = lineDelta exp op > 0
 dollarExpr _ = error "Not an application"
 
-applicativeExpr :: Exp NodeInfo -> Printer ()
+applicativeExpr :: Exp NodeInfo -> Printer s ()
 applicativeExpr exp@InfixApp{} =
   case applicativeArgs of
     Just (first:second:rest) ->
       attemptSingleLine (singleLine first second rest) (multiLine first second rest)
     _ -> prettyNoExt exp
   where
-    singleLine :: Exp NodeInfo -> Exp NodeInfo -> [Exp NodeInfo] -> Printer ()
+    singleLine :: Exp NodeInfo -> Exp NodeInfo -> [Exp NodeInfo] -> Printer s ()
     singleLine first second rest = spaced
                                      [ pretty first
                                      , write "<$>"
@@ -360,7 +360,7 @@
                                      , inter (write " <*> ") $ map pretty rest
                                      ]
 
-    multiLine :: Exp NodeInfo -> Exp NodeInfo -> [Exp NodeInfo] -> Printer ()
+    multiLine :: Exp NodeInfo -> Exp NodeInfo -> [Exp NodeInfo] -> Printer s ()
     multiLine first second rest = do
       pretty first
       depend (write " ") $ do
@@ -392,7 +392,7 @@
     isAp _ = False
 applicativeExpr _ = error "Not an application"
 
-opExpr :: Exp NodeInfo -> Printer ()
+opExpr :: Exp NodeInfo -> Printer s ()
 opExpr (InfixApp _ left op right) = do
   col <- getColumn
   column col $ do
@@ -413,7 +413,7 @@
     pretty right
 opExpr exp = prettyNoExt exp
 
-lambdaExpr :: Exp NodeInfo -> Printer ()
+lambdaExpr :: Exp NodeInfo -> Printer s ()
 lambdaExpr (Lambda _ pats exp) = do
   write "\\"
   spaced $ map pretty pats
@@ -424,7 +424,7 @@
     pretty exp
 lambdaExpr _ = error "Not a lambda"
 
-caseExpr :: Exp NodeInfo -> Printer ()
+caseExpr :: Exp NodeInfo -> Printer s ()
 caseExpr (Case _ exp alts) = do
   depend (write "case ") $ do
     pretty exp
@@ -434,14 +434,14 @@
   writeCaseAlts alts
 caseExpr _ = error "Not a case"
 
-lambdaCaseExpr :: Exp NodeInfo -> Printer ()
+lambdaCaseExpr :: Exp NodeInfo -> Printer s ()
 lambdaCaseExpr (LCase _ alts) = do
   write "\\case"
   newline
   writeCaseAlts alts
 lambdaCaseExpr _ = error "Not a lambda case"
 
-ifExpr :: Exp NodeInfo -> Printer ()
+ifExpr :: Exp NodeInfo -> Printer s ()
 ifExpr (If _ cond thenExpr elseExpr) =
   depend (write "if") $ do
     write " "
@@ -454,7 +454,7 @@
     pretty elseExpr
 ifExpr _ = error "Not an if statement"
 
-writeCaseAlts :: [Alt NodeInfo] -> Printer ()
+writeCaseAlts :: [Alt NodeInfo] -> Printer s ()
 writeCaseAlts alts = do
   allSingle <- and <$> mapM isSingle alts
   withCaseContext True $ indented indentSpaces $
@@ -465,7 +465,7 @@
       else lined $ map (prettyCase Nothing) alts
 
   where
-    isSingle :: Alt NodeInfo -> Printer Bool
+    isSingle :: Alt NodeInfo -> Printer s Bool
     isSingle alt' = fst <$> sandbox
                               (do
                                  line <- gets psLine
@@ -476,7 +476,7 @@
     altPattern :: Alt l -> Pat l
     altPattern (Alt _ p _ _) = p
 
-    patternLen :: Pat NodeInfo -> Printer Int
+    patternLen :: Pat NodeInfo -> Printer s Int
     patternLen pat = fromIntegral <$> fst <$> sandbox
                                                 (do
                                                    col <- getColumn
@@ -484,7 +484,7 @@
                                                    col' <- getColumn
                                                    return $ col' - col)
 
-    prettyCase :: Maybe Int -> Alt NodeInfo -> Printer ()
+    prettyCase :: Maybe Int -> Alt NodeInfo -> Printer s ()
     prettyCase mpatlen (Alt _ p galts mbinds) = do
       -- Padded pattern
       case mpatlen of
@@ -505,7 +505,7 @@
         indented indentSpaces $ depend (write "where ") (pretty binds)
 
 
-recUpdateExpr :: Printer () -> [FieldUpdate NodeInfo] -> Printer ()
+recUpdateExpr :: Printer s () -> [FieldUpdate NodeInfo] -> Printer s ()
 recUpdateExpr expWriter updates = do
   expWriter
   write " "
@@ -531,7 +531,7 @@
         write "}"
 
 rhss :: Extend Rhs
-rhss _ (UnGuardedRhs rhsLoc exp) = do
+rhss (UnGuardedRhs rhsLoc exp) = do
   write " "
   rhsSeparator
   if onNextLine exp
@@ -551,7 +551,7 @@
     onNextLine Let{} = True
     onNextLine Case{} = True
     onNextLine _ = emptyLines > 0
-rhss _ (GuardedRhss _ rs) =
+rhss (GuardedRhss _ rs) =
   lined $ flip map rs $ \a@(GuardedRhs _ stmts exp) -> do
     printComments Before a
     depend (write "| ") $ do
@@ -559,11 +559,11 @@
       rhsRest exp
 
 guardedRhs :: Extend GuardedRhs
-guardedRhs _ (GuardedRhs _ stmts exp) = do
+guardedRhs (GuardedRhs _ stmts exp) = do
   indented 1 $ prefixedLined "," (map (\p -> space >> pretty p) stmts)
   rhsRest exp
 
-rhsRest :: Pretty ast => ast NodeInfo -> Printer ()
+rhsRest :: Pretty ast => ast NodeInfo -> Printer s ()
 rhsRest exp = do
   write " "
   rhsSeparator
@@ -571,7 +571,7 @@
   pretty exp
 
 decls :: Extend Decl
-decls _ (DataDecl _ dataOrNew Nothing declHead constructors mayDeriving) = do
+decls (DataDecl _ dataOrNew Nothing declHead constructors mayDeriving) = do
   pretty dataOrNew
   write " "
   pretty declHead
@@ -592,8 +592,8 @@
   forM_ mayDeriving $ \deriv -> do
     newline
     indented indentSpaces $ pretty deriv
-decls _ (PatBind _ pat rhs mbinds) = funBody [pat] rhs mbinds
-decls _ (FunBind _ matches) =
+decls (PatBind _ pat rhs mbinds) = funBody [pat] rhs mbinds
+decls (FunBind _ matches) =
   lined $ flip map matches $ \match -> do
     (name, pat, rhs, mbinds) <- case match of
                                   Match _ name pat rhs mbinds -> return (name, pat, rhs, mbinds)
@@ -605,9 +605,9 @@
     pretty name
     write " "
     funBody pat rhs mbinds
-decls _ decl = prettyNoExt decl
+decls decl = prettyNoExt decl
 
-funBody :: [Pat NodeInfo] -> Rhs NodeInfo -> Maybe (Binds NodeInfo) -> Printer ()
+funBody :: [Pat NodeInfo] -> Rhs NodeInfo -> Maybe (Binds NodeInfo) -> Printer s ()
 funBody pat rhs mbinds = do
   spaced $ map pretty pat
 
@@ -628,13 +628,13 @@
       newline
       indented indentSpaces $ writeWhereBinds binds
 
-writeWhereBinds :: Binds NodeInfo -> Printer ()
+writeWhereBinds :: Binds NodeInfo -> Printer s ()
 writeWhereBinds ds@(BDecls _ binds) = do
   printComments Before ds
   onSeparateLines binds
 writeWhereBinds binds = prettyNoExt binds
 
-onSeparateLines :: (Pretty ast, Annotated ast) => [ast NodeInfo] -> Printer ()
+onSeparateLines :: (Pretty ast, Annotated ast) => [ast NodeInfo] -> Printer s ()
 onSeparateLines vals@(first:rest) = do
   pretty first
   forM_ (zip vals rest) $ \(prev, cur) -> do
@@ -657,10 +657,10 @@
 isDoBlock _ = False
 
 condecls :: Extend ConDecl
-condecls _ (ConDecl _ name bangty) =
+condecls (ConDecl _ name bangty) =
   depend (pretty name) $
     forM_ bangty $ \ty -> space >> pretty ty
-condecls _ (RecDecl _ name fields) =
+condecls (RecDecl _ name fields) =
   depend (pretty name >> space) $ do
     write "{ "
     case fields of
@@ -678,10 +678,10 @@
           pretty field
           newline
     write "}"
-condecls _ other = prettyNoExt other
+condecls other = prettyNoExt other
 
 alt :: Extend Alt
-alt _ (Alt _ p rhs mbinds) = do
+alt (Alt _ p rhs mbinds) = do
   pretty p
   case rhs of
     UnGuardedRhs{} -> pretty rhs
@@ -692,7 +692,7 @@
       depend (write "where ") (pretty binds)
 
 moduleHead :: Extend ModuleHead
-moduleHead _ (ModuleHead _ name mwarn mexports) = do
+moduleHead (ModuleHead _ name mwarn mexports) = do
   forM_ mwarn pretty
   write "module "
   pretty name
@@ -702,7 +702,7 @@
   write " where"
 
 exportList :: Extend ExportSpecList
-exportList _ (ExportSpecList _ exports) = do
+exportList (ExportSpecList _ exports) = do
   write "("
   if length exports <= maxSingleLineExports
     then do
@@ -733,8 +733,8 @@
     emptyLines = curLine - prevLine
 
 fieldUpdate :: Extend FieldUpdate
-fieldUpdate _ (FieldUpdate _ name val) = do
+fieldUpdate (FieldUpdate _ name val) = do
   pretty name
   write " = "
   pretty val
-fieldUpdate _ upd = prettyNoExt upd
+fieldUpdate upd = prettyNoExt upd
diff --git a/src/HIndent/Styles/JohanTibell.hs b/src/HIndent/Styles/JohanTibell.hs
--- a/src/HIndent/Styles/JohanTibell.hs
+++ b/src/HIndent/Styles/JohanTibell.hs
@@ -61,16 +61,16 @@
 -- do x *
 --    y
 -- is two invalid statements, not one valid infix op.
-stmt :: s -> Stmt NodeInfo -> Printer ()
-stmt _ (Qualifier _ e@(InfixApp _ a op b)) =
+stmt :: Stmt NodeInfo -> Printer s ()
+stmt (Qualifier _ e@(InfixApp _ a op b)) =
   do col <- fmap (psColumn . snd)
                  (sandbox (write ""))
      infixApp e a op b (Just col)
-stmt _ e = prettyNoExt e
+stmt e = prettyNoExt e
 
 -- | Handle do specially and also space out guards more.
-rhs :: t -> Rhs NodeInfo -> Printer ()
-rhs s x =
+rhs :: Rhs NodeInfo -> Printer s ()
+rhs x =
   case x of
     UnGuardedRhs _ (Do _ dos) ->
       swing (write " = do")
@@ -85,13 +85,13 @@
                               gas))
     _ -> do inCase <- gets psInsideCase
             if inCase
-               then unguardedalt s x
-               else unguardedrhs s x
+               then unguardedalt x
+               else unguardedrhs x
 
 -- | Implement dangling right-hand-sides.
-guardedRhs :: t -> GuardedRhs NodeInfo -> Printer ()
+guardedRhs :: GuardedRhs NodeInfo -> Printer s ()
 -- | Handle do specially.
-guardedRhs _ (GuardedRhs _ stmts (Do _ dos)) =
+guardedRhs (GuardedRhs _ stmts (Do _ dos)) =
   do indented 1
               (do prefixedLined
                     ","
@@ -101,27 +101,27 @@
                          stmts))
      swing (write " = do")
            (lined (map pretty dos))
-guardedRhs _ e = prettyNoExt e
+guardedRhs e = prettyNoExt e
 
 -- | Unguarded case alts.
-unguardedalt :: t -> Rhs NodeInfo -> Printer ()
-unguardedalt _ (UnGuardedRhs _ e) =
+unguardedalt :: Rhs NodeInfo -> Printer s ()
+unguardedalt (UnGuardedRhs _ e) =
   do indentSpaces <- getIndentSpaces
      write " -> "
      indented indentSpaces (pretty e)
-unguardedalt _ e = prettyNoExt e
+unguardedalt e = prettyNoExt e
 
-unguardedrhs :: s -> Rhs NodeInfo -> Printer ()
-unguardedrhs _ (UnGuardedRhs _ e) =
+unguardedrhs :: Rhs NodeInfo -> Printer s ()
+unguardedrhs (UnGuardedRhs _ e) =
   do indentSpaces <- getIndentSpaces
      write " = "
      indented indentSpaces (pretty e)
-unguardedrhs _ e = prettyNoExt e
+unguardedrhs e = prettyNoExt e
 
 -- | Expression customizations.
-exp :: t -> Exp NodeInfo -> Printer ()
+exp :: Exp NodeInfo -> Printer s ()
 -- | Space out tuples.
-exp _ (Tuple _ boxed exps) =
+exp (Tuple _ boxed exps) =
   depend (write (case boxed of
                    Unboxed -> "(#"
                    Boxed -> "("))
@@ -136,7 +136,7 @@
                       Boxed -> ")"))
   where p = inter (write ", ") (map pretty exps)
 -- | Space out tuples.
-exp _ (TupleSection _ boxed mexps) =
+exp (TupleSection _ boxed mexps) =
   depend (write (case boxed of
                    Unboxed -> "(#"
                    Boxed -> "("))
@@ -145,10 +145,10 @@
                       Unboxed -> "#)"
                       Boxed -> ")"))
 -- | Infix apps, same algorithm as ChrisDone at the moment.
-exp _ e@(InfixApp _ a op b) =
+exp e@(InfixApp _ a op b) =
   infixApp e a op b Nothing
 -- | If bodies are indented 4 spaces. Handle also do-notation.
-exp _ (If _ if' then' else') =
+exp (If _ if' then' else') =
   do depend (write "if ")
             (pretty if')
      newline
@@ -171,7 +171,7 @@
                      (pretty e)
 -- | App algorithm similar to ChrisDone algorithm, but with no
 -- parent-child alignment.
-exp _ (App _ op a) =
+exp (App _ op a) =
   do orig <- gets psIndentLevel
      headIsShort <- isShort f
      depend (do pretty f
@@ -198,7 +198,7 @@
           flatten f' (a' : b)
         flatten f' as = (((f',as)))
 -- | Space out commas in list.
-exp _ (List _ es) =
+exp (List _ es) =
   do single <- isSingleLiner p
      underflow <- fmap not (isOverflow p)
      if single && underflow
@@ -208,12 +208,12 @@
   where p =
           brackets (inter (write ", ")
                           (map pretty es))
-exp _ (RecUpdate _ exp updates) = recUpdateExpr (pretty exp) updates
-exp _ (RecConstr _ qname updates) = recUpdateExpr (pretty qname) updates
-exp _ e = prettyNoExt e
+exp (RecUpdate _ exp updates) = recUpdateExpr (pretty exp) updates
+exp (RecConstr _ qname updates) = recUpdateExpr (pretty qname) updates
+exp e = prettyNoExt e
 
 -- | Specially format records. Indent where clauses only 2 spaces.
-decl :: t -> Decl NodeInfo -> Printer ()
+decl :: Decl NodeInfo -> Printer s ()
 -- | Pretty print type signatures like
 --
 -- foo :: (Show x,Read x)
@@ -222,7 +222,7 @@
 --     -> (Char -> X -> Y)
 --     -> IO ()
 --
-decl _ (TypeSig _ names ty') =
+decl (TypeSig _ names ty') =
   depend (do inter (write ", ")
                    (map pretty names)
              write " :: ")
@@ -261,7 +261,7 @@
           do overflows <- isOverflow (pretty p)
              oneLine <- isSingleLiner (pretty p)
              return (not overflows && oneLine)
-decl _ (PatBind _ pat rhs' mbinds) =
+decl (PatBind _ pat rhs' mbinds) =
       do pretty pat
          pretty rhs'
          case mbinds of
@@ -273,7 +273,7 @@
                              newline
                              indented 2 (pretty binds))
 -- | Handle records specially for a prettier display (see guide).
-decl _ (DataDecl _ dataornew ctx dhead condecls@[_] mderivs)
+decl (DataDecl _ dataornew ctx dhead condecls@[_] mderivs)
   | any isRecord condecls =
     do depend (do pretty dataornew
                   unless (null condecls) space)
@@ -287,10 +287,10 @@
           depend (write " =")
                  (inter (write "|")
                         (map (depend space . qualConDecl) xs))
-decl _ e = prettyNoExt e
+decl e = prettyNoExt e
 
 -- | Use special record display, used by 'dataDecl' in a record scenario.
-qualConDecl :: QualConDecl NodeInfo -> Printer ()
+qualConDecl :: QualConDecl NodeInfo -> Printer s ()
 qualConDecl x =
     case x of
         QualConDecl _ tyvars ctx d ->
@@ -305,20 +305,20 @@
                      (recDecl d))
 
 -- | Fields are preceded with a space.
-conDecl :: t -> ConDecl NodeInfo -> Printer ()
-conDecl _ (RecDecl _ name fields) =
+conDecl :: ConDecl NodeInfo -> Printer s ()
+conDecl (RecDecl _ name fields) =
   depend (do pretty name
              write " ")
          (do depend (write "{")
                     (prefixedLined ","
                                    (map (depend space . pretty) fields))
              write "}")
-conDecl _ e = prettyNoExt e
+conDecl e = prettyNoExt e
 
 -- | Record decls are formatted like: Foo
 -- { bar :: X
 -- }
-recDecl :: ConDecl NodeInfo -> Printer ()
+recDecl :: ConDecl NodeInfo -> Printer s ()
 recDecl (RecDecl _ name fields) =
   do pretty name
      indentSpaces <- getIndentSpaces
@@ -331,7 +331,7 @@
                 write "} ")
 recDecl r = prettyNoExt r
 
-recUpdateExpr :: Printer () -> [FieldUpdate NodeInfo] -> Printer ()
+recUpdateExpr :: Printer s () -> [FieldUpdate NodeInfo] -> Printer s ()
 recUpdateExpr expWriter updates = do
   expWriter
   newline
@@ -352,14 +352,14 @@
 isRecord _ = False
 
 -- | Does printing the given thing overflow column limit? (e.g. 80)
-isOverflow :: Printer a -> Printer Bool
+isOverflow :: Printer s a -> Printer s Bool
 isOverflow p =
   do (_,st) <- sandbox p
      columnLimit <- getColumnLimit
      return (psColumn st > columnLimit)
 
 -- | Is the given expression a single-liner when printed?
-isSingleLiner :: MonadState PrintState m
+isSingleLiner :: MonadState (PrintState s) m
               => m a -> m Bool
 isSingleLiner p =
   do line <- gets psLine
@@ -368,7 +368,7 @@
 
 -- | Is the expression "short"? Used for app heads.
 isShort :: (Pretty ast)
-        => ast NodeInfo -> Printer (Bool)
+        => ast NodeInfo -> Printer s (Bool)
 isShort p =
   do line <- gets psLine
      orig <- fmap (psColumn . snd) (sandbox (write ""))
@@ -377,7 +377,7 @@
              (psColumn st < orig + shortName))
 
 -- | Is an expression flat?
-isFlat :: Exp NodeInfo -> Printer Bool
+isFlat :: Exp NodeInfo -> Printer s Bool
 isFlat (Lambda _ _ e) = isFlat e
 isFlat (App _ a b) =
   return (isName a && isName b)
@@ -399,8 +399,8 @@
 isFlat _ = return False
 
 -- | rhs on field update on the same line as lhs.
-fieldupdate :: t -> FieldUpdate NodeInfo -> Printer ()
-fieldupdate _ e =
+fieldupdate :: FieldUpdate NodeInfo -> Printer s ()
+fieldupdate e =
   case e of
     FieldUpdate _ n e' -> do pretty n
                              write " = "
@@ -416,7 +416,7 @@
          -> ast1 NodeInfo
          -> ast2 NodeInfo
          -> Maybe Int64
-         -> Printer ()
+         -> Printer s ()
 infixApp e a op b indent =
   do is <- isFlat e
      overflow <- isOverflow
diff --git a/src/HIndent/Types.hs b/src/HIndent/Types.hs
--- a/src/HIndent/Types.hs
+++ b/src/HIndent/Types.hs
@@ -29,25 +29,25 @@
 import Language.Haskell.Exts.SrcLoc
 
 -- | A pretty printing monad.
-newtype Printer a =
-  Printer {runPrinter :: State PrintState a}
-  deriving (Applicative,Monad,Functor,MonadState PrintState)
+newtype Printer s a =
+  Printer {runPrinter :: State (PrintState s) a}
+  deriving (Applicative,Monad,Functor,MonadState (PrintState s))
 
 -- | The state of the pretty printer.
-data PrintState =
-  forall s. PrintState {psIndentLevel :: !Int64 -- ^ Current indentation level.
-                       ,psOutput :: !Builder -- ^ The current output.
-                       ,psNewline :: !Bool -- ^ Just outputted a newline?
-                       ,psColumn :: !Int64 -- ^ Current column.
-                       ,psLine :: !Int64 -- ^ Current line number.
-                       ,psUserState :: !s -- ^ User state.
-                       ,psExtenders :: ![Extender s] -- ^ Extenders.
-                       ,psConfig :: !Config -- ^ Config which styles may or may not pay attention to.
-                       ,psEolComment :: !Bool -- ^ An end of line comment has just been outputted.
-                       ,psInsideCase :: !Bool -- ^ Whether we're in a case statement, used for Rhs printing.
-                       }
+data PrintState s =
+  PrintState {psIndentLevel :: !Int64 -- ^ Current indentation level.
+             ,psOutput :: !Builder -- ^ The current output.
+             ,psNewline :: !Bool -- ^ Just outputted a newline?
+             ,psColumn :: !Int64 -- ^ Current column.
+             ,psLine :: !Int64 -- ^ Current line number.
+             ,psUserState :: !s -- ^ User state.
+             ,psExtenders :: ![Extender s] -- ^ Extenders.
+             ,psConfig :: !Config -- ^ Config which styles may or may not pay attention to.
+             ,psEolComment :: !Bool -- ^ An end of line comment has just been outputted.
+             ,psInsideCase :: !Bool -- ^ Whether we're in a case statement, used for Rhs printing.
+             }
 
-instance Eq PrintState where
+instance Eq (PrintState s) where
   PrintState ilevel out newline col line _ _ _ eolc inc == PrintState ilevel' out' newline' col' line' _ _ _ eolc' inc' =
     (ilevel,out,newline,col,line,eolc, inc) == (ilevel',out',newline',col',line',eolc', inc')
 
@@ -55,8 +55,8 @@
 -- printer was run with, and the current node to print. Use
 -- 'prettyNoExt' to fallback to the built-in printer.
 data Extender s where
-  Extender :: forall s a. (Typeable a) => (s -> a -> Printer ()) -> Extender s
-  CatchAll :: forall s. (forall a. Typeable a => s -> a -> Maybe (Printer ())) -> Extender s
+  Extender :: forall s a. (Typeable a) => (a -> Printer s ()) -> Extender s
+  CatchAll :: forall s. (forall a. Typeable a => s -> a -> Maybe (Printer s ())) -> Extender s
 
 -- | A printer style.
 data Style =
