diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 0.2.1.0
+
+- Add `Monoid` and `Semigroup` instances to `Position`
+
 # 0.2.0.0
 
 - Make `withRecovery` rewind before running recovery
diff --git a/parsix.cabal b/parsix.cabal
--- a/parsix.cabal
+++ b/parsix.cabal
@@ -1,5 +1,5 @@
 name:                parsix
-version:             0.2.0.0
+version:             0.2.1.0
 synopsis:            Parser combinators with slicing, error recovery, and syntax highlighting
 description:         A parser combinator library based on 'parsers' (like 'trifecta') with slicing, error recovery, and syntax highlighted diagnostics
 homepage:            https://github.com/ollef/parsix
diff --git a/src/Text/Parsix/Parser/Internal.hs b/src/Text/Parsix/Parser/Internal.hs
--- a/src/Text/Parsix/Parser/Internal.hs
+++ b/src/Text/Parsix/Parser/Internal.hs
@@ -197,7 +197,7 @@
 -- | @parseText p i file@ runs a parser @p@ on @i@. @file@ is only used for
 -- reporting errors.
 parseText :: Parser a -> Text -> FilePath -> Result a
-parseText p inp file = (\(a, _, _) -> a) <$> runParser p inp file (Position 0 0 0)
+parseText p inp file = (\(a, _, _) -> a) <$> runParser p inp file mempty
 
 -- | @parseString p i file@ runs a parser @p@ on @i@. @file@ is only used for
 -- reporting errors.
diff --git a/src/Text/Parsix/Position.hs b/src/Text/Parsix/Position.hs
--- a/src/Text/Parsix/Position.hs
+++ b/src/Text/Parsix/Position.hs
@@ -18,6 +18,20 @@
   , visualColumn :: !Int
   } deriving (Eq, Ord, Show, Generic)
 
+instance Semigroup Position where
+  p1 <> p2 = Position
+    { codeUnits = codeUnits p1 + codeUnits p2
+    , visualRow = visualRow p1 + visualRow p2
+    , visualColumn =
+      if visualRow p1 == 0 && visualRow p2 == 0 then
+        visualColumn p1 + visualColumn p2
+      else
+        visualColumn p2
+    }
+
+instance Monoid Position where
+  mempty = Position 0 0 0
+
 next :: Char -> Int -> Position -> Position
 next !c !delta !pos = Position
   { codeUnits = codeUnits pos + delta
