diff --git a/heterocephalus.cabal b/heterocephalus.cabal
--- a/heterocephalus.cabal
+++ b/heterocephalus.cabal
@@ -1,5 +1,5 @@
 name:                heterocephalus
-version:             1.0.2.0
+version:             1.0.2.3
 synopsis:            A type-safe template engine for working with popular front end development tools
 description:
     Recent front end development tools and languages are growing fast and have
diff --git a/src/Text/Heterocephalus.hs b/src/Text/Heterocephalus.hs
--- a/src/Text/Heterocephalus.hs
+++ b/src/Text/Heterocephalus.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE TemplateHaskell #-}
 {-# LANGUAGE TupleSections #-}
 {-# LANGUAGE CPP #-}
@@ -50,7 +51,7 @@
 #if MIN_VERSION_base(4,9,0)
 #else
 import Control.Applicative ((<$>), (<*>), Applicative(..))
-import Data.Monoid (mempty)
+import Data.Monoid (Monoid, mempty, mappend)
 #endif
 import Control.Monad (forM)
 import Data.Char (isDigit)
@@ -63,19 +64,26 @@
 import qualified Data.Text.Lazy as TL
 import Language.Haskell.TH.Lib (ExpQ, varE)
 import Language.Haskell.TH.Quote
+       (QuasiQuoter(QuasiQuoter), quoteExp, quoteDec, quotePat, quoteType)
 #if MIN_VERSION_template_haskell(2,9,0)
-import Language.Haskell.TH.Syntax hiding (Module)
+import Language.Haskell.TH.Syntax
+       (Con(..), Dec(..), Exp(..), Info(..), Lit(..), Name(..), Pat(..),
+        Q, Stmt(..), lookupValueName, mkName, nameBase, newName,
+        qAddDependentFile, qRunIO, reify)
 #else
 import Language.Haskell.TH.Syntax
 #endif
 import Text.Blaze (preEscapedToMarkup)
 import Text.Blaze.Html (toHtml)
 import Text.Blaze.Internal (preEscapedText)
-import Text.Hamlet
+import Text.Hamlet (Html, HtmlUrl, HtmlUrlI18n, condH)
 import Text.Hamlet.Parse
+       (Binding(..), DataConstr(..), Module(Module), specialOrIdent)
 import Text.Shakespeare.Base
+       (Deref, Ident(..), Scope, derefToExp, readUtf8File)
 
-import Text.Heterocephalus.Parse (Doc(..), Content(..), parseDoc)
+import Text.Heterocephalus.Parse
+       (Doc(..), Content(..), docFromString)
 
 {- $setup
   >>> :set -XTemplateHaskell -XQuasiQuotes
@@ -98,73 +106,73 @@
   Values declared by 'overwrite' overwrites same name variables.
   Values declared by 'setDefault' are overwritten by same name variables.
 
-  >>> :set -XOverloadedStrings
-  >>> :{
-  >>> putStr $ renderMarkup (
-  >>>   let as = ["<a>", "b"]
-  >>>   in $(compileTextFileWith "templates/sample.txt" $ do
-  >>>     setDefault "as" [| ["foo", "bar"] |]
-  >>>   )
-  >>> )
-  >>> :}
-  sample
-  key: <a>,
-  key: b,
+>>> :set -XOverloadedStrings
+>>> :{
+putStr $ renderMarkup (
+  let as = ["<a>", "b"]
+  in $(compileTextFileWith "templates/sample.txt" $ do
+    setDefault "as" [| ["foo", "bar"] |]
+  )
+)
+:}
+sample
+key: <a>,
+key: b,
 
-  >>> :{
-  >>> putStr $ renderMarkup (
-  >>>   let as = ["<a>", "b"]
-  >>>   in $(compileTextFileWith "templates/sample.txt" $ do
-  >>>     overwrite "as" [| ["foo", "bar"] |]
-  >>>   )
-  >>> )
-  >>> :}
-  sample
-  key: foo,
-  key: bar,
+>>> :{
+putStr $ renderMarkup (
+  let as = ["<a>", "b"]
+  in $(compileTextFileWith "templates/sample.txt" $ do
+    overwrite "as" [| ["foo", "bar"] |]
+  )
+)
+:}
+sample
+key: foo,
+key: bar,
 
-  >>> :{
-  >>> putStr $ renderMarkup (
-  >>>   let as = ["<a>", "b"]
-  >>>   in $(compileTextFileWith "templates/sample.txt" $ do
-  >>>     overwrite "as" [| ["bazbaz", "barbar"] |]
-  >>>     setDefault "as" [| ["foo", "bar"] |]
-  >>>     overwrite "as" [| ["baz", "foobar"] |]
-  >>>   )
-  >>> )
-  >>> :}
-  sample
-  key: baz,
-  key: foobar,
+>>> :{
+putStr $ renderMarkup (
+  let as = ["<a>", "b"]
+  in $(compileTextFileWith "templates/sample.txt" $ do
+    overwrite "as" [| ["bazbaz", "barbar"] |]
+    setDefault "as" [| ["foo", "bar"] |]
+    overwrite "as" [| ["baz", "foobar"] |]
+  )
+)
+:}
+sample
+key: baz,
+key: foobar,
  -}
 compileTextFileWith :: FilePath -> ScopeM () -> Q Exp
 compileTextFileWith fp scopeM = compileFileWith scopeM textSetting fp
 
 {-| Same as 'compileText' but allows the user to specify default values for template parameters.
 
-  >>> :set -XOverloadedStrings
-  >>> :{
-  >>> putStr $ renderMarkup (
-  >>>   let as = ["<a>", "b"]
-  >>>   in $(compileTextFileWithDefault "templates/sample.txt"
-  >>>     [("as", [| ["foo", "bar"] |])]
-  >>>   )
-  >>> )
-  >>> :}
-  sample
-  key: <a>,
-  key: b,
+>>> :set -XOverloadedStrings
+>>> :{
+putStr $ renderMarkup (
+  let as = ["<a>", "b"]
+  in $(compileTextFileWithDefault "templates/sample.txt"
+    [("as", [| ["foo", "bar"] |])]
+  )
+)
+:}
+sample
+key: <a>,
+key: b,
 
-  >>> :{
-  >>> putStr $ renderMarkup (
-  >>>   $(compileTextFileWithDefault "templates/sample.txt"
-  >>>     [("as", [| ["foo", "bar"] |])]
-  >>>   )
-  >>> )
-  >>> :}
-  sample
-  key: foo,
-  key: bar,
+>>> :{
+putStr $ renderMarkup (
+  $(compileTextFileWithDefault "templates/sample.txt"
+    [("as", [| ["foo", "bar"] |])]
+  )
+)
+:}
+sample
+key: foo,
+key: bar,
  -}
 compileTextFileWithDefault :: FilePath -> DefaultScope -> Q Exp
 compileTextFileWithDefault fp scope = compileFileWithDefault scope textSetting fp
@@ -183,73 +191,73 @@
   Values declared by 'overwrite' overwrites same name variables.
   Values declared by 'setDefault' are overwritten by same name variables.
 
-  >>> :set -XOverloadedStrings
-  >>> :{
-  >>> putStr $ renderMarkup (
-  >>>   let as = ["<a>", "b"]
-  >>>   in $(compileHtmlFileWith "templates/sample.txt" $ do
-  >>>     setDefault "as" [| ["foo", "bar"] |]
-  >>>   )
-  >>> )
-  >>> :}
-  sample
-  key: &lt;a&gt;,
-  key: b,
+>>> :set -XOverloadedStrings
+>>> :{
+putStr $ renderMarkup (
+  let as = ["<a>", "b"]
+  in $(compileHtmlFileWith "templates/sample.txt" $ do
+    setDefault "as" [| ["foo", "bar"] |]
+  )
+)
+:}
+sample
+key: &lt;a&gt;,
+key: b,
 
-  >>> :{
-  >>> putStr $ renderMarkup (
-  >>>   let as = ["<a>", "b"]
-  >>>   in $(compileHtmlFileWith "templates/sample.txt" $ do
-  >>>     overwrite "as" [| ["foo", "bar"] |]
-  >>>   )
-  >>> )
-  >>> :}
-  sample
-  key: foo,
-  key: bar,
+>>> :{
+putStr $ renderMarkup (
+  let as = ["<a>", "b"]
+  in $(compileHtmlFileWith "templates/sample.txt" $ do
+    overwrite "as" [| ["foo", "bar"] |]
+  )
+)
+:}
+sample
+key: foo,
+key: bar,
 
-  >>> :{
-  >>> putStr $ renderMarkup (
-  >>>   let as = ["<a>", "b"]
-  >>>   in $(compileHtmlFileWith "templates/sample.txt" $ do
-  >>>     overwrite "as" [| ["bazbaz", "barbar"] |]
-  >>>     setDefault "as" [| ["foo", "bar"] |]
-  >>>     overwrite "as" [| ["baz", "foobar"] |]
-  >>>   )
-  >>> )
-  >>> :}
-  sample
-  key: baz,
-  key: foobar,
+>>> :{
+putStr $ renderMarkup (
+  let as = ["<a>", "b"]
+  in $(compileHtmlFileWith "templates/sample.txt" $ do
+    overwrite "as" [| ["bazbaz", "barbar"] |]
+    setDefault "as" [| ["foo", "bar"] |]
+    overwrite "as" [| ["baz", "foobar"] |]
+  )
+)
+:}
+sample
+key: baz,
+key: foobar,
  -}
 compileHtmlFileWith :: FilePath -> ScopeM () -> Q Exp
 compileHtmlFileWith fp scopeM = compileFileWith scopeM htmlSetting fp
 
 {-| Same as 'compileHtmlFile' but allows the user to specify default values for template parameters.
 
-  >>> :set -XOverloadedStrings
-  >>> :{
-  >>> putStr $ renderMarkup (
-  >>>   let as = ["<a>", "b"]
-  >>>   in $(compileHtmlFileWithDefault "templates/sample.txt"
-  >>>     [("as", [| ["foo", "bar"] |])]
-  >>>   )
-  >>> )
-  >>> :}
-  sample
-  key: &lt;a&gt;,
-  key: b,
+>>> :set -XOverloadedStrings
+:{
+putStr $ renderMarkup (
+  let as = ["<a>", "b"]
+  in $(compileHtmlFileWithDefault "templates/sample.txt"
+    [("as", [| ["foo", "bar"] |])]
+  )
+)
+:}
+sample
+key: &lt;a&gt;,
+key: b,
 
-  >>> :{
-  >>> putStr $ renderMarkup (
-  >>>   $(compileHtmlFileWithDefault "templates/sample.txt"
-  >>>     [("as", [| ["foo", "bar"] |])]
-  >>>   )
-  >>> )
-  >>> :}
-  sample
-  key: foo,
-  key: bar,
+>>> :{
+putStr $ renderMarkup (
+  $(compileHtmlFileWithDefault "templates/sample.txt"
+    [("as", [| ["foo", "bar"] |])]
+  )
+)
+:}
+sample
+key: foo,
+key: bar,
  -}
 compileHtmlFileWithDefault :: FilePath -> DefaultScope -> Q Exp
 compileHtmlFileWithDefault fp scope = compileFileWithDefault scope htmlSetting fp
@@ -350,12 +358,6 @@
     Just x -> varE x
     Nothing -> qexp
 
-docFromString :: String -> [Doc]
-docFromString s =
-  case parseDoc s of
-    Error s' -> error s'
-    Ok d -> d
-
 data HeterocephalusSetting = HeterocephalusSetting
   { escapeExp :: Q Exp
   }
@@ -380,8 +382,8 @@
 type OverwriteDList = DList (Ident, Q Exp)
 
 {- | A type to handle extra scopes.
- - This is opaque type, so use 'setDefault' and 'overwrite'
- - to construct new 'ScopeM'.
+   This is opaque type, so use 'setDefault' and 'overwrite'
+   to construct new 'ScopeM'.
  -}
 data ScopeM a
   = SetDefault Ident ExpQ (ScopeM a)
@@ -400,6 +402,10 @@
 runScopeM (PureScopeM _) =
   (mempty, mempty)
 
+instance Monoid (ScopeM ()) where
+  mempty = pure ()
+  mappend a b = a >> b
+
 instance Functor ScopeM where
   fmap f (SetDefault ident qexp next) =
     SetDefault ident qexp $ fmap f next
@@ -426,15 +432,15 @@
   PureScopeM a >>= f = f a
 
 {-| Constructor for 'ScopeM'.
- - Values declared by this function are overwritten
- - by same name variables exits in scope of render function.
+  Values declared by this function are overwritten
+  by same name variables exits in scope of render function.
  -}
 setDefault :: Ident -> Q Exp -> ScopeM ()
 setDefault ident qexp = SetDefault ident qexp $ pure ()
 
 {-| Constructor for 'ScopeM'.
- - Values declared by this function overwrites
- - same name variables exits in scope of render function.
+  Values declared by this function overwrites
+  same name variables exits in scope of render function.
  -}
 overwrite :: Ident -> Q Exp -> ScopeM ()
 overwrite ident qexp = Overwrite ident qexp $ pure ()
diff --git a/src/Text/Heterocephalus/Parse.hs b/src/Text/Heterocephalus/Parse.hs
--- a/src/Text/Heterocephalus/Parse.hs
+++ b/src/Text/Heterocephalus/Parse.hs
@@ -10,12 +10,16 @@
 #else
 import Control.Applicative ((<$>))
 #endif
-import Control.Monad
+import Control.Monad (guard, void)
 import Data.Char (isUpper)
-import Data.Data
-import Text.Parsec.Prim (Parsec)
-import Text.ParserCombinators.Parsec hiding (Line)
+import Data.Data (Data)
+import Data.Typeable (Typeable)
+import Text.Parsec
+       (Parsec, (<?>), (<|>), alphaNum, between, char, choice, eof, many,
+        many1, manyTill, noneOf, oneOf, option, optional, parse, sepBy,
+        skipMany, spaces, string, try)
 import Text.Shakespeare.Base
+       (Ident(Ident), Deref, parseDeref, parseHash)
 
 import Text.Hamlet.Parse
 
@@ -37,7 +41,7 @@
              | ContentVar Deref
     deriving (Show, Eq, Read, Data, Typeable)
 
-type UserParser a = Parsec String a
+type UserParser = Parsec String ()
 
 docFromString :: String -> [Doc]
 docFromString s =
@@ -62,54 +66,76 @@
 controlsToDocs (NoControl c:cs) = DocContent c : controlsToDocs cs
 controlsToDocs cs = error $ "Parse error: " ++ show cs
 
--- TODO parse elseif
-parseConds :: Int -> [Control] -> ([Control], Maybe [Control], [Control])
+-- | Parse conditional 'Control' statements (@if@, @else@, @endif@) into a
+-- three-tuple.
+--
+-- TODO: parse elseif
+parseConds
+  :: Int
+  -- ^ Current recursive depth of parsing conditional statements.
+  -> [Control]
+  -- ^ Input 'Control' statements.  This should be every statement AFTER the
+  -- initial 'ControlIf' statement.
+  -> ([Control], Maybe [Control], [Control])
+  -- ^ Tuple with three different sets of 'Control' statements.  The first
+  -- @['Control']@ is all of the statements under the @if@ block.  The second
+  -- @'Maybe' ['Control']@ is all the control statements under the @else@
+  -- block.  The third @['Control']@ is the rest of the 'Control' statements
+  -- after this conditional block.
 parseConds _ [] = error "No endif found"
-parseConds depth (x:xs')
+parseConds depth (x:xs)
   | depth < 0 =
     error "A `endif` keyword without any corresponding `if` was found."
-  | depth == 0 && isEndIf x = ([], Nothing, xs')
+  | depth == 0 && isEndIf x = ([], Nothing, xs)
   | depth == 0 && isElse x =
-    let (ys, may, zs) = parseConds depth xs'
+    let (ys, may, zs) = parseConds depth xs
     in case may of
          Nothing -> ([], Just ys, zs)
          Just _ ->
            error "A `if` clause can not have more than one `else` keyword."
   | isEndIf x =
-    let (ys, may, zs) = parseConds (depth - 1) xs'
+    let (ys, may, zs) = parseConds (depth - 1) xs
     in (x : ys, may, zs)
   | isIf x =
-    let (ys, may, zs) = parseConds (depth + 1) xs'
+    let (ys, may, zs) = parseConds (depth + 1) xs
     in (x : ys, may, zs)
   | otherwise =
-    let (ys, may, zs) = parseConds depth xs'
+    let (ys, may, zs) = parseConds depth xs
     in (x : ys, may, zs)
   where
+    isIf :: Control -> Bool
     isIf (ControlIf _) = True
     isIf _ = False
+
+    isEndIf :: Control -> Bool
     isEndIf ControlEndIf = True
     isEndIf _ = False
+
+    isElse :: Control -> Bool
     isElse ControlElse = True
     isElse _ = False
 
 parseReps :: Int -> [Control] -> ([Control], [Control])
 parseReps _ [] = error "No endforall found"
-parseReps depth (x:xs')
+parseReps depth (x:xs)
   | depth < 0 =
     error "A `endforall` keyword without any corresponding `for` was found."
-  | depth == 0 && isEndForall x = ([], xs')
+  | depth == 0 && isEndForall x = ([], xs)
   | isEndForall x =
-    let (ys, zs) = parseReps (depth - 1) xs'
+    let (ys, zs) = parseReps (depth - 1) xs
     in (x : ys, zs)
   | isForall x =
-    let (ys, zs) = parseReps (depth + 1) xs'
+    let (ys, zs) = parseReps (depth + 1) xs
     in (x : ys, zs)
   | otherwise =
-    let (ys, zs) = parseReps depth xs'
+    let (ys, zs) = parseReps depth xs
     in (x : ys, zs)
   where
+    isEndForall :: Control -> Bool
     isEndForall ControlEndForall = True
     isEndForall _ = False
+
+    isForall :: Control -> Bool
     isForall (ControlForall _ _) = True
     isForall _ = False
 
@@ -119,34 +145,40 @@
     Left e -> Error $ show e
     Right x -> Ok x
 
-lineControl :: UserParser () [Control]
+lineControl :: UserParser [Control]
 lineControl = manyTill control $ try eof >> return ()
 
-control :: UserParser () Control
+control :: UserParser Control
 control = controlHash <|> controlPercent <|> controlReg
   where
+    controlPercent :: UserParser Control
     controlPercent = do
       x <- parsePercent
       case x of
         Left str -> return (NoControl $ ContentRaw str)
         Right ctrl -> return ctrl
+
+    controlHash :: UserParser Control
     controlHash = do
       x <- parseHash
       return . NoControl $
         case x of
           Left str -> ContentRaw str
           Right deref -> ContentVar deref
+
+    controlReg :: UserParser Control
     controlReg = (NoControl . ContentRaw) <$> many (noneOf "#%")
 
-parsePercent :: UserParser () (Either String Control)
+parsePercent :: UserParser (Either String Control)
 parsePercent = do
   a <- parseControl '%'
   optional eol
   return a
  where
-  eol = (char '\n' >> return ()) <|> (string "\r\n" >> return ())
+  eol :: UserParser ()
+  eol = void (char '\n') <|> void (string "\r\n")
 
-parseControl :: Char -> UserParser () (Either String Control)
+parseControl :: Char -> UserParser (Either String Control)
 parseControl c = do
   _ <- char c
   (char '\\' >> return (Left [c])) <|>
@@ -160,30 +192,41 @@
     return (Left [c])
 
 
-parseControl' :: UserParser () Control
+parseControl' :: UserParser Control
 parseControl' =
   try parseForall <|> try parseEndForall <|> try parseIf <|> try parseElse <|>
   try parseEndIf
   where
+    parseForall :: UserParser Control
     parseForall = do
       _ <- try $ string "forall"
       spaces
       (x, y) <- binding
       return $ ControlForall x y
+
+    parseEndForall :: UserParser Control
     parseEndForall = do
       _ <- try $ string "endforall"
       return $ ControlEndForall
+
+    parseIf :: UserParser Control
     parseIf = do
       _ <- try $ string "if"
       spaces
       x <- parseDeref
       return $ ControlIf x
+
+    parseElse :: UserParser Control
     parseElse = do
       _ <- try $ string "else"
       return $ ControlElse
+
+    parseEndIf :: UserParser Control
     parseEndIf = do
       _ <- try $ string "endif"
       return $ ControlEndIf
+
+    binding :: UserParser (Deref, Binding)
     binding = do
       y <- identPattern
       spaces
@@ -192,76 +235,118 @@
       x <- parseDeref
       _ <- spaceTabs
       return (x, y)
-    spaceTabs :: Parser String
+
+    spaceTabs :: UserParser String
     spaceTabs = many $ oneOf " \t"
-    ident :: Parser Ident
-    ident =
-      do i <- many1 (alphaNum <|> char '_' <|> char '\'')
-         white
-         return (Ident i) <?> "identifier"
+
+    ident :: UserParser Ident
+    ident = do
+      i <- many1 (alphaNum <|> char '_' <|> char '\'')
+      white
+      return (Ident i) <?> "identifier"
+
+    parens :: UserParser a -> UserParser a
     parens = between (char '(' >> white) (char ')' >> white)
+
+    brackets :: UserParser a -> UserParser a
     brackets = between (char '[' >> white) (char ']' >> white)
+
+    braces :: UserParser a -> UserParser a
     braces = between (char '{' >> white) (char '}' >> white)
+
+    comma :: UserParser ()
     comma = char ',' >> white
+
+    atsign :: UserParser ()
     atsign = char '@' >> white
+
+    equals :: UserParser ()
     equals = char '=' >> white
+
+    white :: UserParser ()
     white = skipMany $ char ' '
+
+    wildDots :: UserParser ()
     wildDots = string ".." >> white
+
+    isVariable :: Ident -> Bool
     isVariable (Ident (x:_)) = not (isUpper x)
     isVariable (Ident []) = error "isVariable: bad identifier"
+
+    isConstructor :: Ident -> Bool
     isConstructor (Ident (x:_)) = isUpper x
     isConstructor (Ident []) = error "isConstructor: bad identifier"
-    identPattern :: Parser Binding
+
+    identPattern :: UserParser Binding
     identPattern = gcon True <|> apat
       where
+        apat :: UserParser Binding
         apat = choice [varpat, gcon False, parens tuplepat, brackets listpat]
-        varpat =
-          do v <-
-               try $ do
-                 v <- ident
-                 guard (isVariable v)
-                 return v
-             option (BindVar v) $ do
-               atsign
-               b <- apat
-               return (BindAs v b) <?> "variable"
-        gcon :: Bool -> Parser Binding
-        gcon allowArgs =
-          do c <-
-               try $ do
-                 c <- dataConstr
-                 return c
-             choice
-               [ record c
-               , fmap (BindConstr c) (guard allowArgs >> many apat)
-               , return (BindConstr c [])
-               ] <?> "constructor"
+
+        varpat :: UserParser Binding
+        varpat = do
+          v <-
+            try $ do
+              v <- ident
+              guard (isVariable v)
+              return v
+          option (BindVar v) $ do
+            atsign
+            b <- apat
+            return (BindAs v b) <?> "variable"
+
+        gcon :: Bool -> UserParser Binding
+        gcon allowArgs = do
+          c <-
+            try $ do
+              c <- dataConstr
+              return c
+          choice
+            [ record c
+            , fmap (BindConstr c) (guard allowArgs >> many apat)
+            , return (BindConstr c [])
+            ] <?>
+            "constructor"
+
+        dataConstr :: UserParser DataConstr
         dataConstr = do
           p <- dcPiece
           ps <- many dcPieces
           return $ toDataConstr p ps
+
+        dcPiece :: UserParser String
         dcPiece = do
           x@(Ident y) <- ident
           guard $ isConstructor x
           return y
+
+        dcPieces :: UserParser String
         dcPieces = do
           _ <- char '.'
           dcPiece
+
+        toDataConstr :: String -> [String] -> DataConstr
         toDataConstr x [] = DCUnqualified $ Ident x
         toDataConstr x (y:ys) = go (x :) y ys
           where
+            go :: ([String] -> [String]) -> String -> [String] -> DataConstr
             go front next [] = DCQualified (Module $ front []) (Ident next)
             go front next (rest:rests) = go (front . (next :)) rest rests
+
+        record :: DataConstr -> UserParser Binding
         record c =
           braces $ do
-            (fields, wild) <- option ([], False) $ go
+            (fields, wild) <- option ([], False) go
             return (BindRecord c fields wild)
           where
+            go :: UserParser ([(Ident, Binding)], Bool)
             go =
               (wildDots >> return ([], True)) <|>
               (do x <- recordField
                   (xs, wild) <- option ([], False) (comma >> go)
                   return (x : xs, wild))
+
+        recordField :: UserParser (Ident, Binding)
         recordField = do
           field <- ident
           p <-
@@ -269,10 +354,14 @@
               (BindVar field) -- support punning
               (equals >> identPattern)
           return (field, p)
+
+        tuplepat :: UserParser Binding
         tuplepat = do
           xs <- identPattern `sepBy` comma
           return $
             case xs of
               [x] -> x
               _ -> BindTuple xs
+
+        listpat :: UserParser Binding
         listpat = BindList <$> identPattern `sepBy` comma
