diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+0.6
+---
+* Annotate `Value` with file positions
+* Derive `Generic1` instances for `Value`
+
 0.5.1
 ---
 * Allow trailing commas in lists and section lists
diff --git a/config-value.cabal b/config-value.cabal
--- a/config-value.cabal
+++ b/config-value.cabal
@@ -1,5 +1,5 @@
 name:                config-value
-version:             0.5.1
+version:             0.6
 synopsis:            Simple, layout-based value language similar to YAML or JSON
 license:             MIT
 license-file:        LICENSE
@@ -32,7 +32,7 @@
                        Config.Pretty,
                        Config.Value
 
-  build-depends:       base       >= 4.5     && < 4.11,
+  build-depends:       base       >= 4.8     && < 4.11,
                        array      >= 0.4     && < 0.6,
                        pretty     >= 1.1.1.0 && < 1.2,
                        text       >= 1.2.0.4 && < 1.3
diff --git a/dist/build/Config/Parser.hs b/dist/build/Config/Parser.hs
--- a/dist/build/Config/Parser.hs
+++ b/dist/build/Config/Parser.hs
@@ -5,7 +5,7 @@
 module Config.Parser (parseValue) where
 
 import Config.Value   (Section(..), Value(..), Atom(..))
-import Config.Tokens  (Located(..), Token)
+import Config.Tokens  (Located(..), Token, Position)
 import qualified Config.Tokens as T
 import qualified Data.Array as Happy_Data_Array
 import qualified Data.Bits as Bits
@@ -21,64 +21,64 @@
 #else
 type HappyAny = forall a . a
 #endif
-happyIn4 :: (Value) -> (HappyAbsSyn )
+happyIn4 :: (Value Position) -> (HappyAbsSyn )
 happyIn4 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyIn4 #-}
-happyOut4 :: (HappyAbsSyn ) -> (Value)
+happyOut4 :: (HappyAbsSyn ) -> (Value Position)
 happyOut4 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyOut4 #-}
-happyIn5 :: (Value) -> (HappyAbsSyn )
+happyIn5 :: (Value Position) -> (HappyAbsSyn )
 happyIn5 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyIn5 #-}
-happyOut5 :: (HappyAbsSyn ) -> (Value)
+happyOut5 :: (HappyAbsSyn ) -> (Value Position)
 happyOut5 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyOut5 #-}
-happyIn6 :: (Value) -> (HappyAbsSyn )
+happyIn6 :: (Value Position) -> (HappyAbsSyn )
 happyIn6 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyIn6 #-}
-happyOut6 :: (HappyAbsSyn ) -> (Value)
+happyOut6 :: (HappyAbsSyn ) -> (Value Position)
 happyOut6 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyOut6 #-}
-happyIn7 :: ([Section]) -> (HappyAbsSyn )
+happyIn7 :: ([Section Position]) -> (HappyAbsSyn )
 happyIn7 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyIn7 #-}
-happyOut7 :: (HappyAbsSyn ) -> ([Section])
+happyOut7 :: (HappyAbsSyn ) -> ([Section Position])
 happyOut7 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyOut7 #-}
-happyIn8 :: ([Section]) -> (HappyAbsSyn )
+happyIn8 :: ([Section Position]) -> (HappyAbsSyn )
 happyIn8 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyIn8 #-}
-happyOut8 :: (HappyAbsSyn ) -> ([Section])
+happyOut8 :: (HappyAbsSyn ) -> ([Section Position])
 happyOut8 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyOut8 #-}
-happyIn9 :: ([Section]) -> (HappyAbsSyn )
+happyIn9 :: ([Section Position]) -> (HappyAbsSyn )
 happyIn9 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyIn9 #-}
-happyOut9 :: (HappyAbsSyn ) -> ([Section])
+happyOut9 :: (HappyAbsSyn ) -> ([Section Position])
 happyOut9 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyOut9 #-}
-happyIn10 :: (Section) -> (HappyAbsSyn )
+happyIn10 :: (Section Position) -> (HappyAbsSyn )
 happyIn10 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyIn10 #-}
-happyOut10 :: (HappyAbsSyn ) -> (Section)
+happyOut10 :: (HappyAbsSyn ) -> (Section Position)
 happyOut10 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyOut10 #-}
-happyIn11 :: ([Value]) -> (HappyAbsSyn )
+happyIn11 :: ([Value Position]) -> (HappyAbsSyn )
 happyIn11 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyIn11 #-}
-happyOut11 :: (HappyAbsSyn ) -> ([Value])
+happyOut11 :: (HappyAbsSyn ) -> ([Value Position])
 happyOut11 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyOut11 #-}
-happyIn12 :: ([Value]) -> (HappyAbsSyn )
+happyIn12 :: ([Value Position]) -> (HappyAbsSyn )
 happyIn12 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyIn12 #-}
-happyOut12 :: (HappyAbsSyn ) -> ([Value])
+happyOut12 :: (HappyAbsSyn ) -> ([Value Position])
 happyOut12 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyOut12 #-}
-happyIn13 :: ([Value]) -> (HappyAbsSyn )
+happyIn13 :: ([Value Position]) -> (HappyAbsSyn )
 happyIn13 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyIn13 #-}
-happyOut13 :: (HappyAbsSyn ) -> ([Value])
+happyOut13 :: (HappyAbsSyn ) -> ([Value Position])
 happyOut13 x = Happy_GHC_Exts.unsafeCoerce# x
 {-# INLINE happyOut13 #-}
 happyInTok :: (Located Token) -> (HappyAbsSyn )
@@ -90,7 +90,7 @@
 
 
 happyExpList :: HappyAddr
-happyExpList = HappyA# "\x00\xe0\x4f\x00\x00\xfe\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x03\x00\xfe\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x4f\x00\x00\xbc\x04\x00\x20\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x4f\x00\x00\xbc\x04\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
+happyExpList = HappyA# "\x00\xe0\x4f\x00\x00\xfe\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\xe0\x4f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\x04\x00\xc0\x4b\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\xc0\x4b\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x4f\x00\x00\x00\x00\x00\x00\x00"#
 
 {-# NOINLINE happyExpListPerState #-}
 happyExpListPerState st =
@@ -106,19 +106,19 @@
         f (True, nr) = [token_strs !! nr]
 
 happyActOffsets :: HappyAddr
-happyActOffsets = HappyA# "\x01\x00\x01\x00\x30\x00\x00\x00\x14\x00\x00\x00\xfd\xff\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x0a\x00\x3b\x00\x2e\x00\x2b\x00\x2d\x00\x00\x00\x00\x00\x25\x00\x27\x00\x00\x00\x00\x00\x22\x00\x00\x00\x26\x00\x00\x00\x00\x00\x00\x00\x01\x00\x0a\x00\x00\x00\x26\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
+happyActOffsets = HappyA# "\x01\x00\x01\x00\x2d\x00\x00\x00\x06\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x0a\x00\x2f\x00\x27\x00\x2a\x00\x22\x00\x00\x00\x00\x00\x26\x00\x21\x00\x00\x00\xfd\xff\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x0a\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00"#
 
 happyGotoOffsets :: HappyAddr
-happyGotoOffsets = HappyA# "\x15\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x23\x00\x11\x00\x35\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x0e\x00\x00\x00\xfb\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
+happyGotoOffsets = HappyA# "\x1f\x00\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x0e\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\xfb\xff\x00\x00\x00\x00\x00\x00\x25\x00\x00\x00\x00\x00"#
 
 happyDefActions :: HappyAddr
-happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\xfb\xff\x00\x00\xf4\xff\x00\x00\x00\x00\xf8\xff\xf7\xff\xfa\xff\xf9\xff\x00\x00\xea\xff\xf2\xff\x00\x00\x00\x00\xf1\xff\xef\xff\xe7\xff\x00\x00\xe9\xff\xec\xff\xed\xff\x00\x00\xfc\xff\x00\x00\xfd\xff\xfe\xff\xf3\xff\x00\x00\xe8\xff\xf5\xff\xf0\xff\xf6\xff\xee\xff\xe6\xff\xeb\xff"#
+happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\xfb\xff\x00\x00\xf4\xff\x00\x00\xf8\xff\xf7\xff\xfa\xff\xf9\xff\x00\x00\xea\xff\xf2\xff\x00\x00\x00\x00\xf1\xff\xef\xff\xe7\xff\x00\x00\xe9\xff\xec\xff\x00\x00\xed\xff\x00\x00\xfd\xff\xfe\xff\xf3\xff\x00\x00\xfc\xff\xe8\xff\xf5\xff\xf0\xff\xf6\xff\xee\xff\xe6\xff\x00\x00\xeb\xff"#
 
 happyCheck :: HappyAddr
-happyCheck = HappyA# "\xff\xff\x06\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x0c\x00\x0d\x00\x0a\x00\x02\x00\x03\x00\x04\x00\x05\x00\x02\x00\x07\x00\x06\x00\x02\x00\x0a\x00\x00\x00\x01\x00\x02\x00\x03\x00\x08\x00\x09\x00\x06\x00\x07\x00\x01\x00\x02\x00\x03\x00\x0c\x00\x0d\x00\x06\x00\x07\x00\x01\x00\x02\x00\x03\x00\x01\x00\x06\x00\x06\x00\x07\x00\x01\x00\x02\x00\x03\x00\x09\x00\x08\x00\x06\x00\x07\x00\x01\x00\x02\x00\x03\x00\x08\x00\x0b\x00\x06\x00\x07\x00\x04\x00\x05\x00\x06\x00\x01\x00\x0f\x00\x0e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
+happyCheck = HappyA# "\xff\xff\x06\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x0c\x00\x0d\x00\x0a\x00\x02\x00\x03\x00\x04\x00\x05\x00\x02\x00\x07\x00\x0c\x00\x0d\x00\x0a\x00\x02\x00\x08\x00\x09\x00\x01\x00\x02\x00\x03\x00\x06\x00\x01\x00\x06\x00\x07\x00\x00\x00\x01\x00\x02\x00\x03\x00\x06\x00\x01\x00\x06\x00\x01\x00\x02\x00\x03\x00\x08\x00\x08\x00\x06\x00\x01\x00\x02\x00\x03\x00\x09\x00\x01\x00\x06\x00\x01\x00\x02\x00\x03\x00\x0b\x00\x0f\x00\x06\x00\x04\x00\x05\x00\x06\x00\x0e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
 
 happyTable :: HappyAddr
-happyTable = HappyA# "\x00\x00\x23\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x19\x00\x1a\x00\x0f\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x24\x00\x0e\x00\x1d\x00\x13\x00\x0f\x00\x0f\x00\x02\x00\x03\x00\x04\x00\x14\x00\x15\x00\x05\x00\x06\x00\x25\x00\x03\x00\x04\x00\x1b\x00\x1c\x00\x05\x00\x06\x00\x16\x00\x03\x00\x04\x00\x08\x00\x1f\x00\x05\x00\x06\x00\x17\x00\x03\x00\x04\x00\x21\x00\x20\x00\x05\x00\x06\x00\x02\x00\x03\x00\x04\x00\x22\x00\x23\x00\x05\x00\x06\x00\x10\x00\x11\x00\x12\x00\x08\x00\xff\xff\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
+happyTable = HappyA# "\x00\x00\x22\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x1d\x00\x1e\x00\x0e\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x12\x00\x0d\x00\x19\x00\x1a\x00\x0e\x00\x23\x00\x13\x00\x14\x00\x15\x00\x03\x00\x04\x00\x1b\x00\x07\x00\x05\x00\x16\x00\x0e\x00\x02\x00\x03\x00\x04\x00\x25\x00\x07\x00\x05\x00\x25\x00\x03\x00\x04\x00\x1f\x00\x21\x00\x05\x00\x17\x00\x03\x00\x04\x00\x20\x00\x07\x00\x05\x00\x02\x00\x03\x00\x04\x00\x22\x00\xff\xff\x05\x00\x0f\x00\x10\x00\x11\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
 
 happyReduceArr = Happy_Data_Array.array (1, 25) [
 	(1 , happyReduce_1),
@@ -164,16 +164,18 @@
 	happy_x_1
 	 =  case happyOut7 happy_x_1 of { happy_var_1 -> 
 	happyIn5
-		 (Sections (reverse happy_var_1)
+		 (sections happy_var_1
 	)}
 
-happyReduce_3 = happySpecReduce_2  1# happyReduction_3
-happyReduction_3 happy_x_2
+happyReduce_3 = happySpecReduce_3  1# happyReduction_3
+happyReduction_3 happy_x_3
+	happy_x_2
 	happy_x_1
-	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	 =  case happyOutTok happy_x_1 of { (Located happy_var_1 T.Bullet) -> 
+	case happyOut11 happy_x_2 of { happy_var_2 -> 
 	happyIn5
-		 (List     (reverse happy_var_1)
-	)}
+		 (List happy_var_1 (reverse happy_var_2)
+	)}}
 
 happyReduce_4 = happySpecReduce_1  1# happyReduction_4
 happyReduction_4 happy_x_1
@@ -184,49 +186,51 @@
 
 happyReduce_5 = happySpecReduce_1  2# happyReduction_5
 happyReduction_5 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (Located _ happy_var_1@T.Number{}) -> 
+	 =  case happyOutTok happy_x_1 of { happy_var_1 -> 
 	happyIn6
-		 (number happy_var_1
+		 (number   happy_var_1
 	)}
 
 happyReduce_6 = happySpecReduce_1  2# happyReduction_6
 happyReduction_6 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (Located _ happy_var_1@T.Floating{}) -> 
+	 =  case happyOutTok happy_x_1 of { happy_var_1 -> 
 	happyIn6
 		 (floating happy_var_1
 	)}
 
 happyReduce_7 = happySpecReduce_1  2# happyReduction_7
 happyReduction_7 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (Located _ (T.String happy_var_1)) -> 
+	 =  case happyOutTok happy_x_1 of { happy_var_1 -> 
 	happyIn6
-		 (Text   happy_var_1
+		 (text     happy_var_1
 	)}
 
 happyReduce_8 = happySpecReduce_1  2# happyReduction_8
 happyReduction_8 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (Located _ (T.Atom happy_var_1)) -> 
+	 =  case happyOutTok happy_x_1 of { happy_var_1 -> 
 	happyIn6
-		 (Atom (MkAtom happy_var_1)
+		 (atom     happy_var_1
 	)}
 
 happyReduce_9 = happySpecReduce_3  2# happyReduction_9
 happyReduction_9 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut8 happy_x_2 of { happy_var_2 -> 
+	 =  case happyOutTok happy_x_1 of { (Located happy_var_1 T.OpenMap) -> 
+	case happyOut8 happy_x_2 of { happy_var_2 -> 
 	happyIn6
-		 (Sections (reverse happy_var_2)
-	)}
+		 (Sections happy_var_1 (reverse happy_var_2)
+	)}}
 
 happyReduce_10 = happySpecReduce_3  2# happyReduction_10
 happyReduction_10 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut12 happy_x_2 of { happy_var_2 -> 
+	 =  case happyOutTok happy_x_1 of { (Located happy_var_1 T.OpenList) -> 
+	case happyOut12 happy_x_2 of { happy_var_2 -> 
 	happyIn6
-		 (List (reverse happy_var_2)
-	)}
+		 (List     happy_var_1 (reverse happy_var_2)
+	)}}
 
 happyReduce_11 = happySpecReduce_1  3# happyReduction_11
 happyReduction_11 happy_x_1
@@ -285,18 +289,17 @@
 happyReduce_18 = happySpecReduce_2  6# happyReduction_18
 happyReduction_18 happy_x_2
 	happy_x_1
-	 =  case happyOutTok happy_x_1 of { (Located _ (T.Section happy_var_1)) -> 
+	 =  case happyOutTok happy_x_1 of { happy_var_1 -> 
 	case happyOut5 happy_x_2 of { happy_var_2 -> 
 	happyIn10
-		 (Section happy_var_1 happy_var_2
+		 (section happy_var_1 happy_var_2
 	)}}
 
-happyReduce_19 = happySpecReduce_2  7# happyReduction_19
-happyReduction_19 happy_x_2
-	happy_x_1
-	 =  case happyOut5 happy_x_2 of { happy_var_2 -> 
+happyReduce_19 = happySpecReduce_1  7# happyReduction_19
+happyReduction_19 happy_x_1
+	 =  case happyOut5 happy_x_1 of { happy_var_1 -> 
 	happyIn11
-		 ([happy_var_2]
+		 ([happy_var_1]
 	)}
 
 happyReduce_20 = happyReduce 4# 7# happyReduction_20
@@ -354,16 +357,16 @@
 happyNewToken action sts stk (tk:tks) =
 	let cont i = happyDoAction i tk action sts stk tks in
 	case tk of {
-	Located _ (T.Section happy_dollar_dollar) -> cont 1#;
-	Located _ (T.String happy_dollar_dollar) -> cont 2#;
-	Located _ (T.Atom happy_dollar_dollar) -> cont 3#;
-	Located _ happy_dollar_dollar@T.Number{} -> cont 4#;
-	Located _ happy_dollar_dollar@T.Floating{} -> cont 5#;
-	Located _ T.Bullet -> cont 6#;
-	Located _ T.OpenList -> cont 7#;
+	Located _ T.Section{} -> cont 1#;
+	Located _ T.String{} -> cont 2#;
+	Located _ T.Atom{} -> cont 3#;
+	Located _ T.Number{} -> cont 4#;
+	Located _ T.Floating{} -> cont 5#;
+	Located happy_dollar_dollar T.Bullet -> cont 6#;
+	Located happy_dollar_dollar T.OpenList -> cont 7#;
 	Located _ T.Comma -> cont 8#;
 	Located _ T.CloseList -> cont 9#;
-	Located _ T.OpenMap -> cont 10#;
+	Located happy_dollar_dollar T.OpenMap -> cont 10#;
 	Located _ T.CloseMap -> cont 11#;
 	Located _ T.LayoutSep -> cont 12#;
 	Located _ T.LayoutEnd -> cont 13#;
@@ -392,23 +395,36 @@
 -- | Convert number token to number value. This needs a custom
 -- function like this because there are two value matched from
 -- the constructor.
-number :: Token -> Value
-number = \(T.Number base val) -> Number base val
+number :: Located Token -> Value Position
+number = \(Located a (T.Number base val)) -> Number a base val
 
 -- | Convert floating token to floating value. This needs a custom
 -- function like this because there are two value matched from
 -- the constructor.
-floating :: Token -> Value
-floating = \(T.Floating coef expo) -> Floating coef expo
+floating :: Located Token -> Value Position
+floating = \(Located a (T.Floating coef expo)) -> Floating a coef expo
 
+section :: Located Token -> Value Position -> Section Position
+section = \(Located a (T.Section k)) v -> Section a k v
+
+sections :: [Section Position] -> Value Position
+sections xxs = Sections (sectionAnn x) (x:xs)
+  where x:xs = reverse xxs
+
+text :: Located Token -> Value Position
+text = \(Located a (T.String x)) -> Text a x
+
+atom :: Located Token -> Value Position
+atom = \(Located a (T.Atom x)) -> Atom a (MkAtom x)
+
 errorP :: [Located Token] -> Either (Located Token) a
 errorP xs = Left (head xs)
 
 -- | Attempt to parse a layout annotated token stream or
 -- the token that caused the parse to fail.
 parseValue ::
-  [Located Token]              {- ^ layout annotated token stream -} ->
-  Either (Located Token) Value {- ^ token at failure or result -}
+  [Located Token]                         {- ^ layout annotated token stream -} ->
+  Either (Located Token) (Value Position) {- ^ token at failure or result -}
 parseValue = config
 {-# LINE 1 "templates/GenericTemplate.hs" #-}
 {-# LINE 1 "templates/GenericTemplate.hs" #-}
diff --git a/src/Config.hs b/src/Config.hs
--- a/src/Config.hs
+++ b/src/Config.hs
@@ -239,6 +239,7 @@
   (
   -- * Parsing
     parse
+  , Position(..)
 
   -- * Pretty-printing
   , pretty
@@ -247,53 +248,70 @@
   , Section(..)
   , Value(..)
   , Atom(..)
+  , valueAnn
+
+  -- * Errors
+  , ParseError(..)
   ) where
 
-import Config.Value  (Atom(..), Value(..), Section(..))
-import Config.Parser (parseValue)
-import Config.Pretty (pretty)
-import Config.Lexer  (scanTokens)
-import Config.Tokens (Error(..), Position(..), Located(..), layoutPass, Token)
+import           Config.Value  (Atom(..), Value(..), Section(..), valueAnn)
+import           Config.Parser (parseValue)
+import           Config.Pretty (pretty)
+import           Config.Lexer  (scanTokens)
+import           Config.Tokens (Error(..), Position(..), Located(..), layoutPass, Token)
 import qualified Config.Tokens as T
 
-import Numeric (showIntAtBase)
-import Data.Char (intToDigit)
-import Data.Text (Text)
+import           Control.Exception (Exception(..))
+import           Numeric (showIntAtBase)
+import           Data.Char (intToDigit)
+import           Data.Text (Text)
 import qualified Data.Text as Text
 
 -- | Parse a configuration file and return the result on the
 -- right, or the position of an error on the left.
+--
+-- The resulting value is annotated with source file locations.
+--
 -- Note: Text file lines are terminated by new-lines.
 parse ::
-  Text                {- ^ source text                    -} ->
-  Either String Value {- ^ error message or parsed value  -}
+  Text                               {- ^ source text                    -} ->
+  Either ParseError (Value Position) {- ^ error message or parsed value  -}
 parse txt =
   case parseValue (layoutPass (scanTokens txt)) of
     Right x -> Right x
-    Left (Located posn token) -> Left (explain posn token)
+    Left (Located posn token) -> Left (ParseError posn (explainToken token))
 
-explain :: Position -> Token -> String
-explain posn token
-   = show (posLine   posn) ++ ":"
-  ++ show (posColumn posn) ++ ": "
-  ++ case token of
-       T.Error e     -> explainError e
-       T.Atom atom   -> "parse error: unexpected atom: " ++ Text.unpack atom
-       T.String str  -> "parse error: unexpected string: " ++ show (Text.unpack str)
-       T.Bullet      -> "parse error: unexpected bullet '*'"
-       T.Comma       -> "parse error: unexpected comma ','"
-       T.Section s   -> "parse error: unexpected section: " ++ Text.unpack s
-       T.Number 2  n -> "parse error: unexpected number: 0b" ++ showIntAtBase 2  intToDigit n ""
-       T.Number 8  n -> "parse error: unexpected number: 0o" ++ showIntAtBase 8  intToDigit n ""
-       T.Number 16 n -> "parse error: unexpected number: 0x" ++ showIntAtBase 16 intToDigit n ""
-       T.Number _  n -> "parse error: unexpected number: "   ++ showIntAtBase 10 intToDigit n ""
-       T.OpenList    -> "parse error: unexpected start of list '['"
-       T.CloseList   -> "parse error: unexpected end of list ']'"
-       T.OpenMap     -> "parse error: unexpected start of section '{'"
-       T.CloseMap    -> "parse error: unexpected end of section '}'"
-       T.LayoutSep   -> "parse error: unexpected end of block"
-       T.LayoutEnd   -> "parse error: unexpected end of block"
-       T.EOF         -> "parse error: unexpected end of file"
+-- | Error messages that can occur during parsing annotated with a file position.
+data ParseError = ParseError Position String
+  deriving (Read, Show, Eq, Ord)
+
+-- | 'displayException' implements a pretty format
+instance Exception ParseError where
+  displayException (ParseError posn msg) =
+    "line "    ++ show (posLine   posn) ++
+    " column " ++ show (posColumn posn) ++
+    ": "       ++ msg
+
+explainToken :: Token -> String
+explainToken token =
+  case token of
+    T.Error e     -> explainError e
+    T.Atom atom   -> "parse error: unexpected atom: `" ++ Text.unpack atom ++ "`"
+    T.String str  -> "parse error: unexpected string: " ++ show (Text.unpack str)
+    T.Bullet      -> "parse error: unexpected bullet '*'"
+    T.Comma       -> "parse error: unexpected comma ','"
+    T.Section s   -> "parse error: unexpected section: `" ++ Text.unpack s ++ "`"
+    T.Number 2  n -> "parse error: unexpected number: 0b" ++ showIntAtBase 2  intToDigit n ""
+    T.Number 8  n -> "parse error: unexpected number: 0o" ++ showIntAtBase 8  intToDigit n ""
+    T.Number 16 n -> "parse error: unexpected number: 0x" ++ showIntAtBase 16 intToDigit n ""
+    T.Number _  n -> "parse error: unexpected number: "   ++ showIntAtBase 10 intToDigit n ""
+    T.OpenList    -> "parse error: unexpected start of list '['"
+    T.CloseList   -> "parse error: unexpected end of list ']'"
+    T.OpenMap     -> "parse error: unexpected start of section '{'"
+    T.CloseMap    -> "parse error: unexpected end of section '}'"
+    T.LayoutSep   -> "parse error: unexpected end of block"
+    T.LayoutEnd   -> "parse error: unexpected end of block"
+    T.EOF         -> "parse error: unexpected end of file"
 
 explainError :: Error -> String
 explainError e =
diff --git a/src/Config/Lens.hs b/src/Config/Lens.hs
--- a/src/Config/Lens.hs
+++ b/src/Config/Lens.hs
@@ -9,6 +9,7 @@
   , list
   , values
   , sections
+  , ann
   ) where
 
 import Config.Value
@@ -26,53 +27,64 @@
 key ::
   Applicative f =>
   Text {- ^ section name -} ->
-  (Value -> f Value) -> Value -> f Value
-key i f (Sections xs) = Sections <$> traverse (section i f) xs
-key _ _ v             = pure v
+  (Value a -> f (Value a)) -> Value a -> f (Value a)
+key i f (Sections a xs) = Sections a <$> traverse (section i f) xs
+key _ _ v               = pure v
 
 -- | Apply a function to the 'Value' contained inside the given
 -- 'Value' when it is a section name matches the given name.
 section ::
   Applicative f =>
   Text {- ^ section name -} ->
-  (Value -> f Value) -> Section -> f Section
-section i f s@(Section j v) | i == j = Section j <$> f v
-                            | otherwise = pure s
+  (Value a -> f (Value a)) -> Section a -> f (Section a)
+section i f s@(Section a j v) | i == j    = Section a j <$> f v
+                              | otherwise = pure s
 
 -- | Apply a function to the ['Section'] contained inside the given
 -- 'Value' when it is a @Sections@.
-sections :: Applicative f => ([Section] -> f [Section]) -> Value -> f Value
-sections f (Sections xs) = Sections <$> f xs
-sections _ v             = pure v
+sections :: Applicative f => ([Section a] -> f [Section a]) -> Value a -> f (Value a)
+sections f (Sections a xs) = Sections a <$> f xs
+sections _ v               = pure v
 
 -- | Apply a function to the 'Text' contained inside the given
 -- 'Value' when it is a @Text@.
-text :: Applicative f => (Text -> f Text) -> Value -> f Value
-text f (Text t) = Text <$> f t
-text _ v        = pure v
+text :: Applicative f => (Text -> f Text) -> Value a -> f (Value a)
+text f (Text a t) = Text a <$> f t
+text _ v          = pure v
 
 -- | Apply a function to the 'Text' contained inside the given
 -- 'Value' when it is a @Text@. This traversal is only valid
 -- if the output atom is a valid atom!
-atom :: Applicative f => (Atom -> f Atom) -> Value -> f Value
-atom f (Atom t) = Atom <$> f t
-atom _ v        = pure v
+atom :: Applicative f => (Atom -> f Atom) -> Value a -> f (Value a)
+atom f (Atom a t) = Atom a <$> f t
+atom _ v          = pure v
 
 -- | Apply a function to the 'Integer' contained inside the given
 -- 'Value' when it is a @Number@.
-number :: Applicative f => (Integer -> f Integer) -> Value -> f Value
-number f (Number b n) = Number b <$> f n
-number _ v            = pure v
+number :: Applicative f => (Integer -> f Integer) -> Value a -> f (Value a)
+number f (Number a b n) = Number a b <$> f n
+number _ v              = pure v
 
 -- | Apply a function to the ['Value'] contained inside the given
 -- 'Value' when it is a @List@.
-list :: Applicative f => ([Value] -> f [Value]) -> Value -> f Value
-list f (List xs) = List <$> f xs
-list _ v         = pure v
+list :: Applicative f => ([Value a] -> f [Value a]) -> Value a -> f (Value a)
+list f (List a xs) = List a <$> f xs
+list _ v           = pure v
 
 -- | Apply a function to the 'Value' elements inside the given
 -- 'Value' when it is a @List@.
 --
 -- > values = list . traverse
-values :: Applicative f => (Value -> f Value) -> Value -> f Value
+values :: Applicative f => (Value a -> f (Value a)) -> Value a -> f (Value a)
 values = list . traverse
+
+
+ann :: Functor f => (a -> f a) -> Value a -> f (Value a)
+ann f v =
+  case v of
+    Sections a x   -> (\a' -> Sections a' x  ) <$> f a
+    Number   a x y -> (\a' -> Number   a' x y) <$> f a
+    Floating a x y -> (\a' -> Floating a' x y) <$> f a
+    Text     a x   -> (\a' -> Text     a' x  ) <$> f a
+    Atom     a x   -> (\a' -> Atom     a' x  ) <$> f a
+    List     a x   -> (\a' -> List     a' x  ) <$> f a
diff --git a/src/Config/Parser.y b/src/Config/Parser.y
--- a/src/Config/Parser.y
+++ b/src/Config/Parser.y
@@ -4,23 +4,23 @@
 module Config.Parser (parseValue) where
 
 import Config.Value   (Section(..), Value(..), Atom(..))
-import Config.Tokens  (Located(..), Token)
+import Config.Tokens  (Located(..), Token, Position)
 import qualified Config.Tokens as T
 
 }
 
 %tokentype                      { Located Token                 }
 %token
-SECTION                         { Located _ (T.Section $$)      }
-STRING                          { Located _ (T.String $$)       }
-ATOM                            { Located _ (T.Atom $$)         }
-NUMBER                          { Located _ $$@T.Number{}       }
-FLOATING                        { Located _ $$@T.Floating{}     }
-'*'                             { Located _ T.Bullet            }
-'['                             { Located _ T.OpenList          }
+SECTION                         { Located _ T.Section{}         }
+STRING                          { Located _ T.String{}          }
+ATOM                            { Located _ T.Atom{}            }
+NUMBER                          { Located _ T.Number{}          }
+FLOATING                        { Located _ T.Floating{}        }
+'*'                             { Located $$ T.Bullet            }
+'['                             { Located $$ T.OpenList          }
 ','                             { Located _ T.Comma             }
 ']'                             { Located _ T.CloseList         }
-'{'                             { Located _ T.OpenMap           }
+'{'                             { Located $$ T.OpenMap           }
 '}'                             { Located _ T.CloseMap          }
 SEP                             { Located _ T.LayoutSep         }
 END                             { Located _ T.LayoutEnd         }
@@ -33,48 +33,48 @@
 
 %%
 
-config ::                       { Value                         }
+config ::                       { Value Position                }
   : value EOF                   { $1                            }
 
-value ::                        { Value                         }
-  : sections END                { Sections (reverse $1)         }
-  | list     END                { List     (reverse $1)         }
+value ::                        { Value Position                }
+  : sections END                { sections $1                   }
+  | '*' list END                { List $1 (reverse $2)          }
   | simple                      { $1                            }
 
-simple ::                       { Value                         }
-  : NUMBER                      { number $1                     }
+simple ::                       { Value Position                }
+  : NUMBER                      { number   $1                   }
   | FLOATING                    { floating $1                   }
-  | STRING                      { Text   $1                     }
-  | ATOM                        { Atom (MkAtom $1)              }
-  | '{' inlinesections '}'      { Sections (reverse $2)         }
-  | '[' inlinelist ']'          { List (reverse $2)             }
+  | STRING                      { text     $1                   }
+  | ATOM                        { atom     $1                   }
+  | '{' inlinesections '}'      { Sections $1 (reverse $2) }
+  | '[' inlinelist ']'          { List     $1 (reverse $2) }
 
-sections ::                     { [Section]                     }
+sections ::                     { [Section Position]            }
   :              section        { [$1]                          }
   | sections SEP section        { $3 : $1                       }
 
-inlinesections ::               { [Section]                     }
+inlinesections ::               { [Section Position]            }
   :                             { []                            }
   | inlinesections1             { $1                            }
   | inlinesections1 ','         { $1                            }
 
-inlinesections1 ::              { [Section]                     }
+inlinesections1 ::              { [Section Position]            }
   :                     section { [$1]                          }
   | inlinesections1 ',' section { $3 : $1                       }
 
-section ::                      { Section                       }
-  : SECTION value               { Section $1 $2                 }
+section ::                      { Section Position              }
+  : SECTION value               { section $1 $2                 }
 
-list ::                         { [Value]                       }
-  :          '*' value          { [$2]                          }
+list ::                         { [Value Position]              }
+  :              value          { [$1]                          }
   | list SEP '*' value          { $4 : $1                       }
 
-inlinelist ::                   { [Value]                       }
+inlinelist ::                   { [Value Position]              }
   :                             { []                            }
   | inlinelist1                 { $1                            }
   | inlinelist1 ','             { $1                            }
 
-inlinelist1 ::                  { [Value]                       }
+inlinelist1 ::                  { [Value Position]              }
   :                 simple      { [$1]                          }
   | inlinelist1 ',' simple      { $3 : $1                       }
 
@@ -83,23 +83,36 @@
 -- | Convert number token to number value. This needs a custom
 -- function like this because there are two value matched from
 -- the constructor.
-number :: Token -> Value
-number = \(T.Number base val) -> Number base val
+number :: Located Token -> Value Position
+number = \(Located a (T.Number base val)) -> Number a base val
 
 -- | Convert floating token to floating value. This needs a custom
 -- function like this because there are two value matched from
 -- the constructor.
-floating :: Token -> Value
-floating = \(T.Floating coef expo) -> Floating coef expo
+floating :: Located Token -> Value Position
+floating = \(Located a (T.Floating coef expo)) -> Floating a coef expo
 
+section :: Located Token -> Value Position -> Section Position
+section = \(Located a (T.Section k)) v -> Section a k v
+
+sections :: [Section Position] -> Value Position
+sections xxs = Sections (sectionAnn x) (x:xs)
+  where x:xs = reverse xxs
+
+text :: Located Token -> Value Position
+text = \(Located a (T.String x)) -> Text a x
+
+atom :: Located Token -> Value Position
+atom = \(Located a (T.Atom x)) -> Atom a (MkAtom x)
+
 errorP :: [Located Token] -> Either (Located Token) a
 errorP xs = Left (head xs)
 
 -- | Attempt to parse a layout annotated token stream or
 -- the token that caused the parse to fail.
 parseValue ::
-  [Located Token]              {- ^ layout annotated token stream -} ->
-  Either (Located Token) Value {- ^ token at failure or result -}
+  [Located Token]                         {- ^ layout annotated token stream -} ->
+  Either (Located Token) (Value Position) {- ^ token at failure or result -}
 parseValue = config
 
 }
diff --git a/src/Config/Pretty.hs b/src/Config/Pretty.hs
--- a/src/Config/Pretty.hs
+++ b/src/Config/Pretty.hs
@@ -13,17 +13,17 @@
 -- Sections will nest complex values underneath with
 -- indentation and simple values will be rendered on
 -- the same line as their section.
-pretty :: Value -> Doc
+pretty :: Value a -> Doc
 pretty value =
   case value of
-    Sections [] -> text "{}"
-    Sections xs -> prettySections xs
-    Number b n  -> prettyNum b n
-    Floating c e-> prettyFloating c e
-    Text t      -> prettyText (Text.unpack t)
-    Atom t      -> text (Text.unpack (atomName t))
-    List []     -> text "[]"
-    List xs     -> vcat [ char '*' <+> pretty x | x <- xs ]
+    Sections _ [] -> text "{}"
+    Sections _ xs -> prettySections xs
+    Number _ b n  -> prettyNum b n
+    Floating _ c e-> prettyFloating c e
+    Text _ t      -> prettyText (Text.unpack t)
+    Atom _ t      -> text (Text.unpack (atomName t))
+    List _ []     -> text "[]"
+    List _ xs     -> vcat [ char '*' <+> pretty x | x <- xs ]
 
 
 prettyNum :: Int -> Integer -> Doc
@@ -48,7 +48,7 @@
           | otherwise = (False, char '\\' <> int (fromEnum x))
 
 
-prettySections :: [Section] -> Doc
+prettySections :: [Section a] -> Doc
 prettySections ss = prettySmallSections small $$ rest
   where
   (small,big) = break (isBig . sectionValue) ss
@@ -56,12 +56,12 @@
                   []     -> empty
                   b : bs -> prettyBigSection b $$ prettySections bs
 
-prettyBigSection :: Section -> Doc
+prettyBigSection :: Section a -> Doc
 prettyBigSection s =
   text (Text.unpack (sectionName s)) <> colon
   $$ nest 2 (pretty (sectionValue s))
 
-prettySmallSections :: [Section] -> Doc
+prettySmallSections :: [Section a] -> Doc
 prettySmallSections ss = vcat (map pp annotated)
   where
   annotate s = (Text.length (sectionName s), s)
@@ -69,15 +69,15 @@
   indent     = 1 + maximum (0 : map fst annotated)
   pp (l,s)   = prettySmallSection (indent - l) s
 
-prettySmallSection :: Int -> Section -> Doc
+prettySmallSection :: Int -> Section a -> Doc
 prettySmallSection n s =
   text (Text.unpack (sectionName s)) <> colon <>
     text (replicate n ' ') <> pretty (sectionValue s)
 
-isBig :: Value -> Bool
-isBig (Sections (_:_))  = True
-isBig (List (_:_))      = True
-isBig _                 = False
+isBig :: Value a -> Bool
+isBig (Sections _ (_:_)) = True
+isBig (List _ (_:_))     = True
+isBig _                  = False
 
 
 
diff --git a/src/Config/Tokens.hs b/src/Config/Tokens.hs
--- a/src/Config/Tokens.hs
+++ b/src/Config/Tokens.hs
@@ -13,7 +13,7 @@
 -- | A position in a text file
 data Position = Position
   { posIndex, posLine, posColumn :: {-# UNPACK #-} !Int }
-  deriving (Read, Show)
+  deriving (Read, Show, Ord, Eq)
 
 -- | A value annotated with its text file position
 data Located a = Located
diff --git a/src/Config/Value.hs b/src/Config/Value.hs
--- a/src/Config/Value.hs
+++ b/src/Config/Value.hs
@@ -1,10 +1,4 @@
-{-# LANGUAGE CPP                #-}
-{-# LANGUAGE DeriveGeneric      #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-
-#ifndef MIN_VERSION_base
-#define MIN_VERSION_base(x,y,z) 1
-#endif
+{-# Language DeriveGeneric, DeriveTraversable, DeriveDataTypeable #-}
 
 -- | This module provides the types used in this package for configuration.
 -- Visit "ConfigFile.Parser" to parse values of this type in a convenient
@@ -13,39 +7,35 @@
   ( Section(..)
   , Value(..)
   , Atom(..)
+  , valueAnn
   ) where
 
 import Data.Text    (Text)
 import Data.Data    (Data, Typeable)
 import Data.String  (IsString(..))
-
-#if MIN_VERSION_base(4,6,0)
-import GHC.Generics (Generic)
-#endif
+import GHC.Generics (Generic, Generic1)
 
 -- | A single section of a 'Value'
 --
 -- Example:
 --
 --    * @my-key: my-value@ is @'Section' ('Atom' "my-key") ('Atom' "my-value")@
-data Section = Section
-  { sectionName  :: Text
-  , sectionValue :: Value
+data Section a = Section
+  { sectionAnn   :: a
+  , sectionName  :: Text
+  , sectionValue :: Value a
   }
-  deriving (Eq, Read, Show, Typeable, Data
-#if MIN_VERSION_base(4,6,0)
-           , Generic
-#endif
+  deriving ( Eq, Read, Show, Typeable, Data
+           , Functor, Foldable, Traversable
+           , Generic, Generic1
            )
 
 -- | Wrapper to distinguish 'Atom' from 'Text' by
 -- type in a configuration. Atoms can be constructed
 -- using the @OverloadedStrings@ extension.
 newtype Atom = MkAtom { atomName :: Text }
-  deriving (Eq, Ord, Show, Read, Typeable, Data
-#if MIN_VERSION_base(4,6,0)
+  deriving ( Eq, Ord, Show, Read, Typeable, Data
            , Generic
-#endif
            )
 
 instance IsString Atom where
@@ -60,6 +50,9 @@
 -- the concrete syntax. This allows representing numbers that would
 -- otherwise overflow a 'Double'.
 --
+-- 'Value' is parameterized over an annotation type indented to be used for
+-- file position or other application specific information.
+--
 -- Examples:
 --
 --    * @0xff@ is @'Number' 16 255@
@@ -68,15 +61,25 @@
 --
 --    * @123e10@ is @'Floating' 123 10@
 --    * @123.45@ is @'Floating' 12345 (-2)@
-data Value
-  = Sections [Section] -- ^ lists of key-value pairs
-  | Number   Int Integer -- ^ integer literal base (2, 8, 10, or 16) and integer value
-  | Floating Integer Integer -- ^ coef exponent: coef * 10 ^ exponent
-  | Text     Text -- ^ quoted strings
-  | Atom     Atom -- ^ unquoted strings
-  | List     [Value] -- ^ lists
-  deriving (Eq, Read, Show, Typeable, Data
-#if MIN_VERSION_base(4,6,0)
-           , Generic
-#endif
+data Value a
+  = Sections a [Section a] -- ^ lists of key-value pairs
+  | Number   a Int Integer -- ^ integer literal base (2, 8, 10, or 16) and integer value
+  | Floating a Integer Integer -- ^ coef exponent: coef * 10 ^ exponent
+  | Text     a Text -- ^ quoted strings
+  | Atom     a Atom -- ^ unquoted strings
+  | List     a [Value a] -- ^ lists
+  deriving ( Eq, Read, Show, Typeable, Data
+           , Functor, Foldable, Traversable
+           , Generic, Generic1
            )
+
+-- | Returns the annotation for a value.
+valueAnn :: Value a -> a
+valueAnn v =
+  case v of
+    Sections a _   -> a
+    Number   a _ _ -> a
+    Floating a _ _ -> a
+    Text     a _   -> a
+    Atom     a _   -> a
+    List     a _   -> a
