diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,11 @@
+## 1.0.4.0
+
+* Add `dropEnd` function to the `IsSequence` class, and a specialized implementation for `Text`
+
+## 1.0.3.0
+
+* Add `ensurePrefix` and `ensureSuffix` functions [#141](https://github.com/snoyberg/mono-traversable/pull/141)
+
 ## 1.0.2.1
 
 * Fix test suite for foldl 1.3
diff --git a/mono-traversable.cabal b/mono-traversable.cabal
--- a/mono-traversable.cabal
+++ b/mono-traversable.cabal
@@ -1,5 +1,5 @@
 name:                mono-traversable
-version:             1.0.2.1
+version:             1.0.4.0
 synopsis:            Type classes for mapping, folding, and traversing monomorphic containers
 description:         Monomorphic variants of the Functor, Foldable, and Traversable typeclasses. If you understand Haskell's basic typeclasses, you understand mono-traversable. In addition to what you are used to, it adds on an IsSequence typeclass and has code for marking data structures as non-empty.
 homepage:            https://github.com/snoyberg/mono-traversable
diff --git a/src/Data/Sequences.hs b/src/Data/Sequences.hs
--- a/src/Data/Sequences.hs
+++ b/src/Data/Sequences.hs
@@ -9,7 +9,7 @@
 module Data.Sequences where
 
 import Data.Maybe (fromJust, isJust)
-import Data.Monoid (Monoid, mconcat, mempty)
+import Data.Monoid (Monoid, mconcat, mempty, (<>))
 import Data.MonoTraversable
 import Data.Int (Int64, Int)
 import qualified Data.List as List
@@ -269,6 +269,19 @@
     unsafeDrop :: Index seq -> seq -> seq
     unsafeDrop = drop
 
+    -- | Same as 'drop' but drops from the end of the sequence instead.
+    --
+    -- @
+    -- > 'dropEnd' 3 "abcdefg"
+    -- "abcd"
+    -- > 'dropEnd' 4 ('fromList' [1,2,3,4,5,6] :: 'Vector' 'Int')
+    -- fromList [1,2]
+    -- @
+    --
+    -- @since 1.0.4.0
+    dropEnd :: Index seq -> seq -> seq
+    dropEnd i s = fst $ splitAt (lengthIndex s - i) s
+
     -- | 'partition' takes a predicate and a sequence and returns the pair of
     -- sequences of elements which do and do not satisfy the predicate.
     --
@@ -724,6 +737,7 @@
     splitAt = T.splitAt
     take = T.take
     drop = T.drop
+    dropEnd = T.dropEnd
     partition = T.partition
     uncons = T.uncons
     unsnoc t
@@ -1245,6 +1259,33 @@
   where
     stripSuffixList :: Eq a => [a] -> [a] -> Maybe [a]
     stripSuffixList x' y' = fmap reverse (stripPrefix (reverse x') (reverse y'))
+
+-- | 'ensurePrefix' will add a prefix to a sequence if it doesn't
+-- exist, and otherwise have no effect.
+--
+-- @
+-- > 'ensurePrefix' "foo" "foobar"
+-- "foobar"
+-- > 'ensurePrefix' "abc" "foobar"
+-- "abcfoobar"
+-- @
+--
+-- @since 1.0.3
+ensurePrefix :: (Eq (Element seq), IsSequence seq) => seq -> seq -> seq
+ensurePrefix prefix seq = if isPrefixOf prefix seq then seq else prefix <> seq
+
+-- | Append a suffix to a sequence, unless it already has that suffix.
+--
+-- @
+-- > 'ensureSuffix' "bar" "foobar"
+-- "foobar"
+-- > 'ensureSuffix' "abc" "foobar"
+-- "foobarabc"
+-- @
+--
+-- @since 1.0.3
+ensureSuffix :: (Eq (Element seq), IsSequence seq) => seq -> seq -> seq
+ensureSuffix suffix seq = if isSuffixOf suffix seq then seq else seq <> suffix
 
 -- | 'isPrefixOf' takes two sequences and returns 'True' if the first
 -- sequence is a prefix of the second.
