diff --git a/Setup.hs b/Setup.hs
deleted file mode 100644
--- a/Setup.hs
+++ /dev/null
@@ -1,2 +0,0 @@
-import Distribution.Simple
-main = defaultMain
diff --git a/src/Data/Text/Region/Types.hs b/src/Data/Text/Region/Types.hs
--- a/src/Data/Text/Region/Types.hs
+++ b/src/Data/Text/Region/Types.hs
@@ -22,6 +22,7 @@
 import qualified Data.ByteString.Lazy.Char8 as L
 import Data.Group
 import Data.List
+import Data.Semigroup (Semigroup(..))
 import Data.Text (Text)
 import qualified Data.Text as T
 
@@ -43,6 +44,11 @@
 instance FromJSON Point where
 	parseJSON = withObject "point" $ \v → Point <$> v .: "line" <*> v .: "column"
 
+instance Semigroup Point where
+	Point l c <> Point bl bc
+		| l ≡ 0 = Point bl (c + bc)
+		| otherwise = Point (l + bl) c
+
 instance Monoid Point where
 	mempty = Point 0 0
 	Point l c `mappend` Point bl bc
@@ -99,6 +105,9 @@
 -- This works if we don't use overlapped regions
 newtype Map = Map { mapIso :: Iso' Region Region }
 
+instance Semigroup Map where
+	Map l <> Map r = Map (r . l)
+
 instance Monoid Map where
 	mempty = Map $ iso id id
 	Map l `mappend` Map r = Map (r . l)
@@ -185,7 +194,7 @@
 -- | Edit is several replace actions, applied simultaneously, must not overlap
 newtype Edit s = Edit {
 	_replaces ∷ [Replace s] }
-		deriving (Eq, Show, Monoid)
+		deriving (Eq, Show, Semigroup, Monoid)
 
 makeLenses ''Edit
 
diff --git a/text-region.cabal b/text-region.cabal
--- a/text-region.cabal
+++ b/text-region.cabal
@@ -1,5 +1,5 @@
 name:                text-region
-version:             0.3.0.0
+version:             0.3.1.0
 synopsis:            Marking text regions
 description: Provides functions to update text region positions according to text edit actions
 homepage:            https://github.com/mvoidex/text-region
