diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -3,6 +3,9 @@
 
 Type classes for mapping, folding, and traversing monomorphic containers. Contains even more experimental code for abstracting containers and sequences. 
 
+A polymorphin container is one such as list which has a type variable `[a]`
+A monomorphic container is one such as Text which has a type `Text` that does not expose the underlying characters.
+
 Adding instances
 ----------------
 
@@ -35,6 +38,25 @@
 in your code, and your ready to use ```CustomType a``` with the functions defined in this package.
 
 **Note**: if your type is as _monomorphic container_ without the proper typeclasses, then you will have to provide an implementation. However, this should be fairly simple, as it can be seen [in the code](https://hackage.haskell.org/package/mono-traversable-0.2.0.0/docs/src/Data-MonoTraversable.html#line-234)
+
+
+mono-traversable versuse lens Traversal
+---------------------------------------
+lens is a huge package with a lot of functionality.
+One piece of functionality it exposes is Fold and Traversal which can also be used to deal with monomorphic containers.
+
+You could prefer mono-traversable to using this part of lens because
+
+* There is really no new API to learn. If you know Foldable, you can use MonoFoldable just as easily
+* mono-traversable's typeclass based approach means many methods are included in the class but can easily be given specialised optimized implementations
+* You don't need to explicitly pass around the Traversal
+
+The last point is also a point of inflexibility and points to a use case where you could prefer using a lens Traversal.
+mono-traversable treats ByteString as a sequence of bytes.
+If you want to treat it as both bytes and characters, mono-traversable would require a newtype wrapper around ByteString,
+whereas a lens traversal would just use a different traversal function.
+
+
 
 
 [![Build Status](https://secure.travis-ci.org/snoyberg/mono-traversable.png)](http://travis-ci.org/snoyberg/mono-traversable)
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:             0.3.0.1
+version:             0.3.0.2
 synopsis:            Type classes for mapping, folding, and traversing monomorphic containers
 description:         Monomorphic variants of the Functor, Foldable, and Traversable typeclasses. Contains even more experimental code for abstracting containers and sequences.
 homepage:            https://github.com/snoyberg/mono-traversable
diff --git a/src/Data/Containers.hs b/src/Data/Containers.hs
--- a/src/Data/Containers.hs
+++ b/src/Data/Containers.hs
@@ -41,56 +41,89 @@
 instance Ord k => SetContainer (Map.Map k v) where
     type ContainerKey (Map.Map k v) = k
     member = Map.member
+    {-# INLINE member #-}
     notMember = Map.notMember
+    {-# INLINE notMember #-}
     union = Map.union
+    {-# INLINE union #-}
     difference = Map.difference
+    {-# INLINE difference #-}
     intersection = Map.intersection
+    {-# INLINE intersection #-}
 
 instance (Eq key, Hashable key) => SetContainer (HashMap.HashMap key value) where
     type ContainerKey (HashMap.HashMap key value) = key
     member = HashMap.member
+    {-# INLINE member #-}
     notMember k = not . HashMap.member k
+    {-# INLINE notMember #-}
     union = HashMap.union
+    {-# INLINE union #-}
     difference = HashMap.difference
+    {-# INLINE difference #-}
     intersection = HashMap.intersection
+    {-# INLINE intersection #-}
 
 instance SetContainer (IntMap.IntMap value) where
     type ContainerKey (IntMap.IntMap value) = Int
     member = IntMap.member
+    {-# INLINE member #-}
     notMember = IntMap.notMember
+    {-# INLINE notMember #-}
     union = IntMap.union
+    {-# INLINE union #-}
     difference = IntMap.difference
+    {-# INLINE difference #-}
     intersection = IntMap.intersection
+    {-# INLINE intersection #-}
 
 instance Ord element => SetContainer (Set.Set element) where
     type ContainerKey (Set.Set element) = element
     member = Set.member
+    {-# INLINE member #-}
     notMember = Set.notMember
+    {-# INLINE notMember #-}
     union = Set.union
+    {-# INLINE union #-}
     difference = Set.difference
+    {-# INLINE difference #-}
     intersection = Set.intersection
+    {-# INLINE intersection #-}
 
 instance (Eq element, Hashable element) => SetContainer (HashSet.HashSet element) where
     type ContainerKey (HashSet.HashSet element) = element
     member = HashSet.member
+    {-# INLINE member #-}
     notMember e = not . HashSet.member e
+    {-# INLINE notMember #-}
     union = HashSet.union
+    {-# INLINE union #-}
     difference = HashSet.difference
+    {-# INLINE difference #-}
     intersection = HashSet.intersection
+    {-# INLINE intersection #-}
 
 instance SetContainer IntSet.IntSet where
     type ContainerKey IntSet.IntSet = Int
     member = IntSet.member
+    {-# INLINE member #-}
     notMember = IntSet.notMember
+    {-# INLINE notMember #-}
     union = IntSet.union
+    {-# INLINE union #-}
     difference = IntSet.difference
+    {-# INLINE difference #-}
     intersection = IntSet.intersection
+    {-# INLINE intersection #-}
 
 instance Eq key => SetContainer [(key, value)] where
     type ContainerKey [(key, value)] = key
     member k = List.any ((== k) . fst)
+    {-# INLINE member #-}
     notMember k = not . member k
+    {-# INLINE notMember #-}
     union = List.unionBy ((==) `on` fst)
+    {-# INLINE union #-}
     x `difference` y =
         loop x
       where
@@ -100,6 +133,7 @@
                 Nothing -> (k, v) : loop rest
                 Just _ -> loop rest
     intersection = List.intersectBy ((==) `on` fst)
+    {-# INLINE intersection #-}
 
 -- | A guaranteed-polymorphic @Map@, which allows for more polymorphic versions
 -- of functions.
@@ -115,21 +149,30 @@
 
 instance Ord key => PolyMap (Map.Map key) where
     differenceMap = Map.difference
+    {-# INLINE differenceMap #-}
     --differenceWithMap = Map.differenceWith
     intersectionMap = Map.intersection
+    {-# INLINE intersectionMap #-}
     intersectionWithMap = Map.intersectionWith
+    {-# INLINE intersectionWithMap #-}
 
 instance (Eq key, Hashable key) => PolyMap (HashMap.HashMap key) where
     differenceMap = HashMap.difference
+    {-# INLINE differenceMap #-}
     --differenceWithMap = HashMap.differenceWith
     intersectionMap = HashMap.intersection
+    {-# INLINE intersectionMap #-}
     intersectionWithMap = HashMap.intersectionWith
+    {-# INLINE intersectionWithMap #-}
 
 instance PolyMap IntMap.IntMap where
     differenceMap = IntMap.difference
+    {-# INLINE differenceMap #-}
     --differenceWithMap = IntMap.differenceWith
     intersectionMap = IntMap.intersection
+    {-# INLINE intersectionMap #-}
     intersectionWithMap = IntMap.intersectionWith
+    {-# INLINE intersectionWithMap #-}
 
 class (MonoTraversable map, SetContainer map) => IsMap map where
     -- | In some cases, @MapValue@ and @Element@ will be different, e.g., the
@@ -322,48 +365,78 @@
 instance Ord key => IsMap (Map.Map key value) where
     type MapValue (Map.Map key value) = value
     lookup = Map.lookup
+    {-# INLINE lookup #-}
     insertMap = Map.insert
+    {-# INLINE insertMap #-}
     deleteMap = Map.delete
+    {-# INLINE deleteMap #-}
     singletonMap = Map.singleton
+    {-# INLINE singletonMap #-}
     mapFromList = Map.fromList
+    {-# INLINE mapFromList #-}
     mapToList = Map.toList
+    {-# INLINE mapToList #-}
 
     findWithDefault = Map.findWithDefault
+    {-# INLINE findWithDefault #-}
     insertWith = Map.insertWith
+    {-# INLINE insertWith #-}
     insertWithKey = Map.insertWithKey
+    {-# INLINE insertWithKey #-}
     insertLookupWithKey = Map.insertLookupWithKey
+    {-# INLINE insertLookupWithKey #-}
     adjustMap = Map.adjust
+    {-# INLINE adjustMap #-}
     adjustWithKey = Map.adjustWithKey
+    {-# INLINE adjustWithKey #-}
     updateMap = Map.update
+    {-# INLINE updateMap #-}
     updateWithKey = Map.updateWithKey
+    {-# INLINE updateWithKey #-}
     updateLookupWithKey = Map.updateLookupWithKey
+    {-# INLINE updateLookupWithKey #-}
     alterMap = Map.alter
+    {-# INLINE alterMap #-}
     unionWith = Map.unionWith
+    {-# INLINE unionWith #-}
     unionWithKey = Map.unionWithKey
+    {-# INLINE unionWithKey #-}
     unionsWith = Map.unionsWith
+    {-# INLINE unionsWith #-}
     mapWithKey = Map.mapWithKey
+    {-# INLINE mapWithKey #-}
     mapKeysWith = Map.mapKeysWith
+    {-# INLINE mapKeysWith #-}
 
 instance (Eq key, Hashable key) => IsMap (HashMap.HashMap key value) where
     type MapValue (HashMap.HashMap key value) = value
     lookup = HashMap.lookup
+    {-# INLINE lookup #-}
     insertMap = HashMap.insert
+    {-# INLINE insertMap #-}
     deleteMap = HashMap.delete
+    {-# INLINE deleteMap #-}
     singletonMap = HashMap.singleton
+    {-# INLINE singletonMap #-}
     mapFromList = HashMap.fromList
+    {-# INLINE mapFromList #-}
     mapToList = HashMap.toList
+    {-# INLINE mapToList #-}
 
     --findWithDefault = HashMap.findWithDefault
     insertWith = HashMap.insertWith
+    {-# INLINE insertWith #-}
     --insertWithKey = HashMap.insertWithKey
     --insertLookupWithKey = HashMap.insertLookupWithKey
     adjustMap = HashMap.adjust
+    {-# INLINE adjustMap #-}
     --adjustWithKey = HashMap.adjustWithKey
     --updateMap = HashMap.update
     --updateWithKey = HashMap.updateWithKey
     --updateLookupWithKey = HashMap.updateLookupWithKey
     --alterMap = HashMap.alter
     unionWith = HashMap.unionWith
+    {-# INLINE unionWith #-}
     --unionWithKey = HashMap.unionWithKey
     --unionsWith = HashMap.unionsWith
     --mapWithKey = HashMap.mapWithKey
@@ -372,38 +445,64 @@
 instance IsMap (IntMap.IntMap value) where
     type MapValue (IntMap.IntMap value) = value
     lookup = IntMap.lookup
+    {-# INLINE lookup #-}
     insertMap = IntMap.insert
+    {-# INLINE insertMap #-}
     deleteMap = IntMap.delete
+    {-# INLINE deleteMap #-}
     singletonMap = IntMap.singleton
+    {-# INLINE singletonMap #-}
     mapFromList = IntMap.fromList
+    {-# INLINE mapFromList #-}
     mapToList = IntMap.toList
+    {-# INLINE mapToList #-}
 
     findWithDefault = IntMap.findWithDefault
+    {-# INLINE findWithDefault #-}
     insertWith = IntMap.insertWith
+    {-# INLINE insertWith #-}
     insertWithKey = IntMap.insertWithKey
+    {-# INLINE insertWithKey #-}
     insertLookupWithKey = IntMap.insertLookupWithKey
+    {-# INLINE insertLookupWithKey #-}
     adjustMap = IntMap.adjust
+    {-# INLINE adjustMap #-}
     adjustWithKey = IntMap.adjustWithKey
+    {-# INLINE adjustWithKey #-}
     updateMap = IntMap.update
+    {-# INLINE updateMap #-}
     updateWithKey = IntMap.updateWithKey
+    {-# INLINE updateWithKey #-}
     --updateLookupWithKey = IntMap.updateLookupWithKey
     alterMap = IntMap.alter
+    {-# INLINE alterMap #-}
     unionWith = IntMap.unionWith
+    {-# INLINE unionWith #-}
     unionWithKey = IntMap.unionWithKey
+    {-# INLINE unionWithKey #-}
     unionsWith = IntMap.unionsWith
+    {-# INLINE unionsWith #-}
     mapWithKey = IntMap.mapWithKey
+    {-# INLINE mapWithKey #-}
 #if MIN_VERSION_containers(0, 5, 0)
     mapKeysWith = IntMap.mapKeysWith
+    {-# INLINE mapKeysWith #-}
 #endif
 
 instance Eq key => IsMap [(key, value)] where
     type MapValue [(key, value)] = value
     lookup = List.lookup
+    {-# INLINE lookup #-}
     insertMap k v = ((k, v):) . deleteMap k
+    {-# INLINE insertMap #-}
     deleteMap k = List.filter ((/= k) . fst)
+    {-# INLINE deleteMap #-}
     singletonMap k v = [(k, v)]
+    {-# INLINE singletonMap #-}
     mapFromList = id
+    {-# INLINE mapFromList #-}
     mapToList = id
+    {-# INLINE mapToList #-}
 
 class (SetContainer set, Element set ~ ContainerKey set) => IsSet set where
     insertSet :: Element set -> set -> set
@@ -414,24 +513,39 @@
 
 instance Ord element => IsSet (Set.Set element) where
     insertSet = Set.insert
+    {-# INLINE insertSet #-}
     deleteSet = Set.delete
+    {-# INLINE deleteSet #-}
     singletonSet = Set.singleton
+    {-# INLINE singletonSet #-}
     setFromList = Set.fromList
+    {-# INLINE setFromList #-}
     setToList = Set.toList
+    {-# INLINE setToList #-}
 
 instance (Eq element, Hashable element) => IsSet (HashSet.HashSet element) where
     insertSet = HashSet.insert
+    {-# INLINE insertSet #-}
     deleteSet = HashSet.delete
+    {-# INLINE deleteSet #-}
     singletonSet = HashSet.singleton
+    {-# INLINE singletonSet #-}
     setFromList = HashSet.fromList
+    {-# INLINE setFromList #-}
     setToList = HashSet.toList
+    {-# INLINE setToList #-}
 
 instance IsSet IntSet.IntSet where
     insertSet = IntSet.insert
+    {-# INLINE insertSet #-}
     deleteSet = IntSet.delete
+    {-# INLINE deleteSet #-}
     singletonSet = IntSet.singleton
+    {-# INLINE singletonSet #-}
     setFromList = IntSet.fromList
+    {-# INLINE setFromList #-}
     setToList = IntSet.toList
+    {-# INLINE setToList #-}
 
 
 -- | zip operations on MonoFunctors.
@@ -445,15 +559,27 @@
     ozip     = ByteString.zip
     ounzip   = ByteString.unzip
     ozipWith f xs = ByteString.pack . ByteString.zipWith f xs
+    {-# INLINE ozip #-}
+    {-# INLINE ounzip #-}
+    {-# INLINE ozipWith #-}
 instance MonoZip LByteString.ByteString where
     ozip     = LByteString.zip
     ounzip   = LByteString.unzip
     ozipWith f xs = LByteString.pack . LByteString.zipWith f xs
+    {-# INLINE ozip #-}
+    {-# INLINE ounzip #-}
+    {-# INLINE ozipWith #-}
 instance MonoZip Text.Text where
     ozip     = Text.zip
     ounzip   = (Text.pack *** Text.pack) . List.unzip
     ozipWith = Text.zipWith
+    {-# INLINE ozip #-}
+    {-# INLINE ounzip #-}
+    {-# INLINE ozipWith #-}
 instance MonoZip LText.Text where
     ozip     = LText.zip
     ounzip   = (LText.pack *** LText.pack) . List.unzip
     ozipWith = LText.zipWith
+    {-# INLINE ozip #-}
+    {-# INLINE ounzip #-}
+    {-# INLINE ozipWith #-}
diff --git a/src/Data/MinLen.hs b/src/Data/MinLen.hs
--- a/src/Data/MinLen.hs
+++ b/src/Data/MinLen.hs
@@ -68,24 +68,32 @@
 
 mlcons :: IsSequence seq => Element seq -> MinLen nat seq -> MinLen (Succ nat) seq
 mlcons e (MinLen seq) = MinLen (cons e seq)
+{-# INLINE mlcons #-}
 
 mlappend :: IsSequence seq => MinLen x seq -> MinLen y seq -> MinLen (AddNat x y) seq
 mlappend (MinLen x) (MinLen y) = MinLen (x `mappend` y)
+{-# INLINE mlappend #-}
 
 head :: MonoTraversable mono => MinLen (Succ nat) mono -> Element mono
 head = headEx . unMinLen
+{-# INLINE head #-}
 
 last :: MonoTraversable mono => MinLen (Succ nat) mono -> Element mono
 last = lastEx . unMinLen
+{-# INLINE last #-}
 
 tail :: IsSequence seq => MinLen (Succ nat) seq -> MinLen nat seq
 tail = MinLen . tailEx . unMinLen
+{-# INLINE tail #-}
 
 init :: IsSequence seq => MinLen (Succ nat) seq -> MinLen nat seq
 init = MinLen . initEx . unMinLen
+{-# INLINE init #-}
 
 instance GrowingAppend mono => Semigroup (MinLen nat mono) where
     MinLen x <> MinLen y = MinLen (x <> y)
+    {-# INLINE (<>) #-}
 
 mlunion :: GrowingAppend mono => MinLen x mono -> MinLen y mono -> MinLen (MaxNat x y) mono
 mlunion (MinLen x) (MinLen y) = MinLen (x <> y)
+{-# INLINE mlunion #-}
diff --git a/src/Data/MonoTraversable.hs b/src/Data/MonoTraversable.hs
--- a/src/Data/MonoTraversable.hs
+++ b/src/Data/MonoTraversable.hs
@@ -139,15 +139,20 @@
     omap :: (Element mono -> Element mono) -> mono -> mono
     default omap :: (Functor f, Element (f a) ~ a, f a ~ mono) => (a -> a) -> f a -> f a
     omap = fmap
+    {-# INLINE omap #-}
 
 instance MonoFunctor S.ByteString where
     omap = S.map
+    {-# INLINE omap #-}
 instance MonoFunctor L.ByteString where
     omap = L.map
+    {-# INLINE omap #-}
 instance MonoFunctor T.Text where
     omap = T.map
+    {-# INLINE omap #-}
 instance MonoFunctor TL.Text where
     omap = TL.map
+    {-# INLINE omap #-}
 instance MonoFunctor [a]
 instance MonoFunctor (IO a)
 instance MonoFunctor (ZipList a)
@@ -189,51 +194,66 @@
 instance Functor f => MonoFunctor (Static f a b)
 instance U.Unbox a => MonoFunctor (U.Vector a) where
     omap = U.map
+    {-# INLINE omap #-}
 instance VS.Storable a => MonoFunctor (VS.Vector a) where
     omap = VS.map
+    {-# INLINE omap #-}
 
 class MonoFoldable mono where
     ofoldMap :: Monoid m => (Element mono -> m) -> mono -> m
     default ofoldMap :: (t a ~ mono, a ~ Element (t a), F.Foldable t, Monoid m) => (Element mono -> m) -> mono -> m
     ofoldMap = F.foldMap
+    {-# INLINE ofoldMap #-}
 
     ofoldr :: (Element mono -> b -> b) -> b -> mono -> b
     default ofoldr :: (t a ~ mono, a ~ Element (t a), F.Foldable t) => (Element mono -> b -> b) -> b -> mono -> b
     ofoldr = F.foldr
+    {-# INLINE ofoldr #-}
 
     ofoldl' :: (a -> Element mono -> a) -> a -> mono -> a
     default ofoldl' :: (t b ~ mono, b ~ Element (t b), F.Foldable t) => (a -> Element mono -> a) -> a -> mono -> a
     ofoldl' = F.foldl'
+    {-# INLINE ofoldl' #-}
 
     otoList :: mono -> [Element mono]
     otoList t = build (\ mono n -> ofoldr mono n t)
+    {-# INLINE otoList #-}
 
     oall :: (Element mono -> Bool) -> mono -> Bool
     oall f = getAll . ofoldMap (All . f)
+    {-# INLINE oall #-}
 
     oany :: (Element mono -> Bool) -> mono -> Bool
     oany f = getAny . ofoldMap (Any . f)
+    {-# INLINE oany #-}
 
     onull :: mono -> Bool
     onull = oall (const False)
+    {-# INLINE onull #-}
 
     olength :: mono -> Int
     olength = ofoldl' (\i _ -> i + 1) 0
+    {-# INLINE olength #-}
 
     olength64 :: mono -> Int64
     olength64 = ofoldl' (\i _ -> i + 1) 0
+    {-# INLINE olength64 #-}
 
     ocompareLength :: Integral i => mono -> i -> Ordering
     ocompareLength c0 i0 = olength c0 `compare` fromIntegral i0 -- FIXME more efficient implementation
+    {-# INLINE ocompareLength #-}
 
     otraverse_ :: (MonoFoldable mono, Applicative f) => (Element mono -> f b) -> mono -> f ()
     otraverse_ f = ofoldr ((*>) . f) (pure ())
+    {-# INLINE otraverse_ #-}
 
     ofor_ :: (MonoFoldable mono, Applicative f) => mono -> (Element mono -> f b) -> f ()
     ofor_ = flip otraverse_
+    {-# INLINE ofor_ #-}
 
     omapM_ :: (MonoFoldable mono, Monad m) => (Element mono -> m b) -> mono -> m ()
     omapM_ f = ofoldr ((>>) . f) (return ())
+    {-# INLINE omapM_ #-}
 
     oforM_ :: (MonoFoldable mono, Monad m) => mono -> (Element mono -> m b) -> m ()
     oforM_ = flip omapM_
@@ -242,6 +262,7 @@
     ofoldlM :: (MonoFoldable mono, Monad m) => (a -> Element mono -> m a) -> a -> mono -> m a
     ofoldlM f z0 xs = ofoldr f' return xs z0
       where f' x k z = f z x >>= k
+    {-# INLINE ofoldlM #-}
 
     -- | Note: this is a partial function. On an empty @MonoFoldable@, it will
     -- throw an exception. See "Data.NonNull" for a total version of this
@@ -257,6 +278,7 @@
     default ofoldr1Ex :: (t a ~ mono, a ~ Element (t a), F.Foldable t)
                            => (a -> a -> a) -> mono -> a
     ofoldr1Ex = F.foldr1
+    {-# INLINE ofoldr1Ex #-}
 
     -- | Note: this is a partial function. On an empty @MonoFoldable@, it will
     -- throw an exception. See "Data.NonNull" for a total version of this
@@ -265,18 +287,23 @@
     default ofoldl1Ex' :: (t a ~ mono, a ~ Element (t a), F.Foldable t)
                             => (a -> a -> a) -> mono -> a
     ofoldl1Ex' = F.foldl1
+    {-# INLINE ofoldl1Ex' #-}
 
     headEx :: mono -> Element mono
     headEx = ofoldr1Ex const
+    {-# INLINE headEx #-}
 
     lastEx :: mono -> Element mono
     lastEx = ofoldl1Ex' (flip const)
+    {-# INLINE lastEx #-}
 
     unsafeHead :: mono -> Element mono
     unsafeHead = headEx
+    {-# INLINE unsafeHead #-}
 
     unsafeLast :: mono -> Element mono
     unsafeLast = lastEx
+    {-# INLINE unsafeLast #-}
 
 instance MonoFoldable S.ByteString where
     ofoldMap f = ofoldr (mappend . f) mempty
@@ -297,12 +324,25 @@
                     _ <- f (Unsafe.inlinePerformIO (peek ptr))
                     loop (ptr `plusPtr` 1)
         loop start
-    {-# INLINE omapM_ #-}
     ofoldr1Ex = S.foldr1
     ofoldl1Ex' = S.foldl1'
     headEx = S.head
     lastEx = S.last
     unsafeHead = SU.unsafeHead
+    {-# INLINE ofoldMap #-}
+    {-# INLINE ofoldr #-}
+    {-# INLINE ofoldl' #-}
+    {-# INLINE otoList #-}
+    {-# INLINE oall #-}
+    {-# INLINE oany #-}
+    {-# INLINE onull #-}
+    {-# INLINE olength #-}
+    {-# INLINE omapM_ #-}
+    {-# INLINE ofoldr1Ex #-}
+    {-# INLINE ofoldl1Ex' #-}
+    {-# INLINE headEx #-}
+    {-# INLINE lastEx #-}
+    {-# INLINE unsafeHead #-}
 instance MonoFoldable L.ByteString where
     ofoldMap f = ofoldr (mappend . f) mempty
     ofoldr = L.foldr
@@ -313,11 +353,24 @@
     onull = L.null
     olength64 = L.length
     omapM_ f = omapM_ (omapM_ f) . L.toChunks
-    {-# INLINE omapM_ #-}
     ofoldr1Ex = L.foldr1
     ofoldl1Ex' = L.foldl1'
     headEx = L.head
     lastEx = L.last
+    {-# INLINE ofoldMap #-}
+    {-# INLINE ofoldr #-}
+    {-# INLINE ofoldl' #-}
+    {-# INLINE otoList #-}
+    {-# INLINE oall #-}
+    {-# INLINE oany #-}
+    {-# INLINE onull #-}
+    {-# INLINE olength64 #-}
+    {-# INLINE omapM_ #-}
+    {-# INLINE ofoldr1Ex #-}
+    {-# INLINE ofoldl1Ex' #-}
+    {-# INLINE headEx #-}
+    {-# INLINE lastEx #-}
+    {-# INLINE unsafeHead #-}
 instance MonoFoldable T.Text where
     ofoldMap f = ofoldr (mappend . f) mempty
     ofoldr = T.foldr
@@ -331,6 +384,20 @@
     ofoldl1Ex' = T.foldl1'
     headEx = T.head
     lastEx = T.last
+    {-# INLINE ofoldMap #-}
+    {-# INLINE ofoldr #-}
+    {-# INLINE ofoldl' #-}
+    {-# INLINE otoList #-}
+    {-# INLINE oall #-}
+    {-# INLINE oany #-}
+    {-# INLINE onull #-}
+    {-# INLINE olength #-}
+    {-# INLINE omapM_ #-}
+    {-# INLINE ofoldr1Ex #-}
+    {-# INLINE ofoldl1Ex' #-}
+    {-# INLINE headEx #-}
+    {-# INLINE lastEx #-}
+    {-# INLINE unsafeHead #-}
 instance MonoFoldable TL.Text where
     ofoldMap f = ofoldr (mappend . f) mempty
     ofoldr = TL.foldr
@@ -344,6 +411,20 @@
     ofoldl1Ex' = TL.foldl1'
     headEx = TL.head
     lastEx = TL.last
+    {-# INLINE ofoldMap #-}
+    {-# INLINE ofoldr #-}
+    {-# INLINE ofoldl' #-}
+    {-# INLINE otoList #-}
+    {-# INLINE oall #-}
+    {-# INLINE oany #-}
+    {-# INLINE onull #-}
+    {-# INLINE olength #-}
+    {-# INLINE omapM_ #-}
+    {-# INLINE ofoldr1Ex #-}
+    {-# INLINE ofoldl1Ex' #-}
+    {-# INLINE headEx #-}
+    {-# INLINE lastEx #-}
+    {-# INLINE unsafeHead #-}
 instance MonoFoldable IntSet where
     ofoldMap f = ofoldr (mappend . f) mempty
     ofoldr = IntSet.foldr
@@ -353,6 +434,20 @@
     olength = IntSet.size
     ofoldr1Ex f = ofoldr1Ex f . IntSet.toList
     ofoldl1Ex' f = ofoldl1Ex' f . IntSet.toList
+    {-# INLINE ofoldMap #-}
+    {-# INLINE ofoldr #-}
+    {-# INLINE ofoldl' #-}
+    {-# INLINE otoList #-}
+    {-# INLINE oall #-}
+    {-# INLINE oany #-}
+    {-# INLINE onull #-}
+    {-# INLINE olength #-}
+    {-# INLINE omapM_ #-}
+    {-# INLINE ofoldr1Ex #-}
+    {-# INLINE ofoldl1Ex' #-}
+    {-# INLINE headEx #-}
+    {-# INLINE lastEx #-}
+    {-# INLINE unsafeHead #-}
 instance MonoFoldable [a] where
     otoList = id
     {-# INLINE otoList #-}
@@ -364,6 +459,8 @@
 instance MonoFoldable (Seq a) where
     headEx = flip Seq.index 1
     lastEx xs = Seq.index xs (Seq.length xs - 1)
+    {-# INLINE headEx #-}
+    {-# INLINE lastEx #-}
 instance MonoFoldable (ViewL a)
 instance MonoFoldable (ViewR a)
 instance MonoFoldable (IntMap a)
@@ -386,6 +483,20 @@
     lastEx = V.last
     unsafeHead = V.unsafeHead
     unsafeLast = V.unsafeLast
+    {-# INLINE ofoldMap #-}
+    {-# INLINE ofoldr #-}
+    {-# INLINE ofoldl' #-}
+    {-# INLINE otoList #-}
+    {-# INLINE oall #-}
+    {-# INLINE oany #-}
+    {-# INLINE onull #-}
+    {-# INLINE olength #-}
+    {-# INLINE omapM_ #-}
+    {-# INLINE ofoldr1Ex #-}
+    {-# INLINE ofoldl1Ex' #-}
+    {-# INLINE headEx #-}
+    {-# INLINE lastEx #-}
+    {-# INLINE unsafeHead #-}
 instance MonoFoldable (Set e)
 instance MonoFoldable (HashSet e)
 instance U.Unbox a => MonoFoldable (U.Vector a) where
@@ -403,6 +514,20 @@
     lastEx = U.last
     unsafeHead = U.unsafeHead
     unsafeLast = U.unsafeLast
+    {-# INLINE ofoldMap #-}
+    {-# INLINE ofoldr #-}
+    {-# INLINE ofoldl' #-}
+    {-# INLINE otoList #-}
+    {-# INLINE oall #-}
+    {-# INLINE oany #-}
+    {-# INLINE onull #-}
+    {-# INLINE olength #-}
+    {-# INLINE omapM_ #-}
+    {-# INLINE ofoldr1Ex #-}
+    {-# INLINE ofoldl1Ex' #-}
+    {-# INLINE headEx #-}
+    {-# INLINE lastEx #-}
+    {-# INLINE unsafeHead #-}
 instance VS.Storable a => MonoFoldable (VS.Vector a) where
     ofoldMap f = ofoldr (mappend . f) mempty
     ofoldr = VS.foldr
@@ -418,6 +543,20 @@
     lastEx = VS.last
     unsafeHead = VS.unsafeHead
     unsafeLast = VS.unsafeLast
+    {-# INLINE ofoldMap #-}
+    {-# INLINE ofoldr #-}
+    {-# INLINE ofoldl' #-}
+    {-# INLINE otoList #-}
+    {-# INLINE oall #-}
+    {-# INLINE oany #-}
+    {-# INLINE onull #-}
+    {-# INLINE olength #-}
+    {-# INLINE omapM_ #-}
+    {-# INLINE ofoldr1Ex #-}
+    {-# INLINE ofoldl1Ex' #-}
+    {-# INLINE headEx #-}
+    {-# INLINE lastEx #-}
+    {-# INLINE unsafeHead #-}
 instance MonoFoldable (Either a b) where
     ofoldMap f = ofoldr (mappend . f) mempty
     ofoldr f b (Right a) = f a b
@@ -438,26 +577,44 @@
     ofoldr1Ex _ (Right x) = x
     ofoldl1Ex' _ (Left _) = Prelude.error "ofoldl1Ex' on Either"
     ofoldl1Ex' _ (Right x) = x
+    {-# INLINE ofoldMap #-}
+    {-# INLINE ofoldr #-}
+    {-# INLINE ofoldl' #-}
+    {-# INLINE otoList #-}
+    {-# INLINE oall #-}
+    {-# INLINE oany #-}
+    {-# INLINE onull #-}
+    {-# INLINE olength #-}
+    {-# INLINE omapM_ #-}
+    {-# INLINE ofoldr1Ex #-}
+    {-# INLINE ofoldl1Ex' #-}
+    {-# INLINE headEx #-}
+    {-# INLINE lastEx #-}
+    {-# INLINE unsafeHead #-}
 
 -- | like Data.List.head, but not partial
 headMay :: MonoFoldable mono => mono -> Maybe (Element mono)
 headMay mono
     | onull mono = Nothing
     | otherwise = Just (headEx mono)
+{-# INLINE headMay #-}
 
 -- | like Data.List.last, but not partial
 lastMay :: MonoFoldable mono => mono -> Maybe (Element mono)
 lastMay mono
     | onull mono = Nothing
     | otherwise = Just (lastEx mono)
+{-# INLINE lastMay #-}
 
 -- | The 'sum' function computes the sum of the numbers of a structure.
 osum :: (MonoFoldable mono, Num (Element mono)) => mono -> Element mono
 osum = getSum . ofoldMap Sum
+{-# INLINE osum #-}
 
 -- | The 'product' function computes the product of the numbers of a structure.
 oproduct :: (MonoFoldable mono, Num (Element mono)) => mono -> Element mono
 oproduct = Data.Monoid.getProduct . ofoldMap Data.Monoid.Product
+{-# INLINE oproduct #-}
 
 class (MonoFoldable mono, Monoid mono) => MonoFoldableMonoid mono where -- FIXME is this really just MonoMonad?
     oconcatMap :: (Element mono -> mono) -> mono -> mono
@@ -465,18 +622,23 @@
 instance (MonoFoldable (t a), Monoid (t a)) => MonoFoldableMonoid (t a) -- FIXME
 instance MonoFoldableMonoid S.ByteString where
     oconcatMap = S.concatMap
+    {-# INLINE oconcatMap #-}
 instance MonoFoldableMonoid L.ByteString where
     oconcatMap = L.concatMap
+    {-# INLINE oconcatMap #-}
 instance MonoFoldableMonoid T.Text where
     oconcatMap = T.concatMap
+    {-# INLINE oconcatMap #-}
 instance MonoFoldableMonoid TL.Text where
     oconcatMap = TL.concatMap
+    {-# INLINE oconcatMap #-}
 
 -- | A typeclass for @MonoFoldable@s containing elements which are an instance
 -- of @Ord@.
 class (MonoFoldable mono, Ord (Element mono)) => MonoFoldableOrd mono where
     maximumEx :: mono -> Element mono
     maximumEx = maximumByEx compare
+    {-# INLINE maximumEx #-}
 
     maximumByEx :: (Element mono -> Element mono -> Ordering) -> mono -> Element mono
     maximumByEx f =
@@ -486,9 +648,11 @@
             case f x y of
                 LT -> y
                 _  -> x
+    {-# INLINE maximumByEx #-}
 
     minimumEx :: mono -> Element mono
     minimumEx = minimumByEx compare
+    {-# INLINE minimumEx #-}
 
     minimumByEx :: (Element mono -> Element mono -> Ordering) -> mono -> Element mono
     minimumByEx f =
@@ -498,6 +662,7 @@
             case f x y of
                 GT -> y
                 _  -> x
+    {-# INLINE minimumByEx #-}
 
 instance MonoFoldableOrd S.ByteString where
     maximumEx = S.maximum
@@ -537,6 +702,10 @@
     maximumByEx = V.maximumBy
     minimumEx   = V.minimum
     minimumByEx = V.minimumBy
+    {-# INLINE maximumEx #-}
+    {-# INLINE maximumByEx #-}
+    {-# INLINE minimumEx #-}
+    {-# INLINE minimumByEx #-}
 instance Ord e => MonoFoldableOrd (Set e)
 instance Ord e => MonoFoldableOrd (HashSet e)
 instance (U.Unbox a, Ord a) => MonoFoldableOrd (U.Vector a) where
@@ -544,17 +713,26 @@
     maximumByEx = U.maximumBy
     minimumEx   = U.minimum
     minimumByEx = U.minimumBy
+    {-# INLINE maximumEx #-}
+    {-# INLINE maximumByEx #-}
+    {-# INLINE minimumEx #-}
+    {-# INLINE minimumByEx #-}
 instance (Ord a, VS.Storable a) => MonoFoldableOrd (VS.Vector a) where
     maximumEx   = VS.maximum
     maximumByEx = VS.maximumBy
     minimumEx   = VS.minimum
     minimumByEx = VS.minimumBy
+    {-# INLINE maximumEx #-}
+    {-# INLINE maximumByEx #-}
+    {-# INLINE minimumEx #-}
+    {-# INLINE minimumByEx #-}
 instance Ord b => MonoFoldableOrd (Either a b) where
 
 maximumMay :: MonoFoldableOrd mono => mono -> Maybe (Element mono)
 maximumMay mono
     | onull mono = Nothing
     | otherwise = Just (maximumEx mono)
+{-# INLINE maximumMay #-}
 
 maximumByMay :: MonoFoldableOrd mono
              => (Element mono -> Element mono -> Ordering)
@@ -563,11 +741,13 @@
 maximumByMay f mono
     | onull mono = Nothing
     | otherwise = Just (maximumByEx f mono)
+{-# INLINE maximumByMay #-}
 
 minimumMay :: MonoFoldableOrd mono => mono -> Maybe (Element mono)
 minimumMay mono
     | onull mono = Nothing
     | otherwise = Just (minimumEx mono)
+{-# INLINE minimumMay #-}
 
 minimumByMay :: MonoFoldableOrd mono
              => (Element mono -> Element mono -> Ordering)
@@ -576,6 +756,7 @@
 minimumByMay f mono
     | onull mono = Nothing
     | otherwise = Just (minimumByEx f mono)
+{-# INLINE minimumByMay #-}
 
 class (MonoFunctor mono, MonoFoldable mono) => MonoTraversable mono where
     otraverse :: Applicative f => (Element mono -> f (Element mono)) -> mono -> f mono
@@ -584,18 +765,28 @@
     omapM :: Monad m => (Element mono -> m (Element mono)) -> mono -> m mono
     default omapM :: (Traversable t, mono ~ t a, a ~ Element mono, Monad m) => (Element mono -> m (Element mono)) -> mono -> m mono
     omapM = mapM
+    {-# INLINE otraverse #-}
+    {-# INLINE omapM #-}
 instance MonoTraversable S.ByteString where
     otraverse f = fmap S.pack . traverse f . S.unpack
     omapM f = liftM S.pack . mapM f . S.unpack
+    {-# INLINE otraverse #-}
+    {-# INLINE omapM #-}
 instance MonoTraversable L.ByteString where
     otraverse f = fmap L.pack . traverse f . L.unpack
     omapM f = liftM L.pack . mapM f . L.unpack
+    {-# INLINE otraverse #-}
+    {-# INLINE omapM #-}
 instance MonoTraversable T.Text where
     otraverse f = fmap T.pack . traverse f . T.unpack
     omapM f = liftM T.pack . mapM f . T.unpack
+    {-# INLINE otraverse #-}
+    {-# INLINE omapM #-}
 instance MonoTraversable TL.Text where
     otraverse f = fmap TL.pack . traverse f . TL.unpack
     omapM f = liftM TL.pack . mapM f . TL.unpack
+    {-# INLINE otraverse #-}
+    {-# INLINE omapM #-}
 instance MonoTraversable [a]
 instance MonoTraversable (Maybe a)
 instance MonoTraversable (Tree a)
@@ -612,17 +803,25 @@
 instance U.Unbox a => MonoTraversable (U.Vector a) where
     otraverse f = fmap U.fromList . traverse f . U.toList
     omapM = U.mapM
+    {-# INLINE otraverse #-}
+    {-# INLINE omapM #-}
 instance VS.Storable a => MonoTraversable (VS.Vector a) where
     otraverse f = fmap VS.fromList . traverse f . VS.toList
     omapM = VS.mapM
+    {-# INLINE otraverse #-}
+    {-# INLINE omapM #-}
 instance MonoTraversable (Either a b) where
     otraverse _ (Left a) = pure (Left a)
     otraverse f (Right b) = fmap Right (f b)
     omapM _ (Left a) = return (Left a)
     omapM f (Right b) = liftM Right (f b)
+    {-# INLINE otraverse #-}
+    {-# INLINE omapM #-}
 
 ofor :: (MonoTraversable mono, Applicative f) => mono -> (Element mono -> f (Element mono)) -> f mono
 ofor = flip otraverse
+{-# INLINE ofor #-}
 
 oforM :: (MonoTraversable mono, Monad f) => mono -> (Element mono -> f (Element mono)) -> f mono
 oforM = flip omapM
+{-# INLINE oforM #-}
diff --git a/src/Data/NonNull.hs b/src/Data/NonNull.hs
--- a/src/Data/NonNull.hs
+++ b/src/Data/NonNull.hs
@@ -8,10 +8,10 @@
 -- | Warning, this is Experimental!
 --
 -- Data.NonNull attempts to extend the concepts from
--- 'Data.List.NonEmpty' to any 'MonoFoldable'.
+-- "Data.List.NonEmpty" to any 'MonoFoldable'.
 --
 -- 'NonNull' is a typeclass for a container with 1 or more elements.
--- 'Data.List.NonEmpty' and 'NotEmpty a' are members of the typeclass
+-- "Data.List.NonEmpty" and 'NotEmpty a' are members of the typeclass
 module Data.NonNull (
     NonNull(..)
   , fromNonEmpty
@@ -46,6 +46,7 @@
 import qualified Data.Monoid as Monoid
 import Data.Data
 import qualified Data.List.NonEmpty as NE
+import Control.Monad (liftM)
 
 data NullError = NullError String deriving (Show, Typeable)
 instance Exception NullError
@@ -183,7 +184,9 @@
 type instance Element (NotEmpty seq) = Element seq
 deriving instance MonoFunctor seq => MonoFunctor (NotEmpty seq)
 deriving instance MonoFoldable seq => MonoFoldable (NotEmpty seq)
-deriving instance MonoTraversable seq => MonoTraversable (NotEmpty seq)
+instance MonoTraversable seq => MonoTraversable (NotEmpty seq) where
+    otraverse f = fmap NotEmpty . otraverse f . fromNotEmpty
+    omapM f = liftM NotEmpty . omapM f . fromNotEmpty
 
 -- | Helper functions for type inferences.
 --
diff --git a/src/Data/Sequences.hs b/src/Data/Sequences.hs
--- a/src/Data/Sequences.hs
+++ b/src/Data/Sequences.hs
@@ -18,7 +18,7 @@
 import qualified Data.Text as T
 import qualified Data.Text.Lazy as TL
 import Control.Category
-import Control.Arrow ((***), second)
+import Control.Arrow ((***), first, second)
 import Control.Monad (liftM)
 import qualified Data.Sequence as Seq
 import qualified Data.Vector as V
@@ -82,7 +82,7 @@
 
     dropWhile :: (Element seq -> Bool) -> seq -> seq
     dropWhile f = fromList . List.dropWhile f . otoList
-    
+
     takeWhile :: (Element seq -> Bool) -> seq -> seq
     takeWhile f = fromList . List.takeWhile f . otoList
 
@@ -106,15 +106,12 @@
 
     partition :: (Element seq -> Bool) -> seq -> (seq, seq)
     partition f = (fromList *** fromList) . List.partition f . otoList
-    
+
     uncons :: seq -> Maybe (Element seq, seq)
     uncons = fmap (second fromList) . uncons . otoList
 
     unsnoc :: seq -> Maybe (seq, Element seq)
-    unsnoc seq =
-        case reverse (otoList seq) of
-            [] -> Nothing
-            x:xs -> Just (fromList (reverse xs), x)
+    unsnoc = fmap (first fromList) . unsnoc . otoList
 
     filter :: (Element seq -> Bool) -> seq -> seq
     filter f = fromList . List.filter f . otoList
@@ -133,7 +130,7 @@
     groupBy :: (Element seq -> Element seq -> Bool) -> seq -> [seq]
     groupBy f = fmap fromList . List.groupBy f . otoList
 
-    -- | Similar to standard 'groupBy', but operates on the whole collection, 
+    -- | Similar to standard 'groupBy', but operates on the whole collection,
     -- not just the consecutive items.
     groupAllOn :: Eq b => (Element seq -> b) -> seq -> [seq]
     groupAllOn f = fmap fromList . groupAllOn f . otoList
@@ -155,39 +152,70 @@
 
     unsafeInit :: seq -> seq
     unsafeInit = initEx
+    {-# INLINE fromList #-}
+    {-# INLINE break #-}
+    {-# INLINE span #-}
+    {-# INLINE dropWhile #-}
+    {-# INLINE takeWhile #-}
+    {-# INLINE splitAt #-}
+    {-# INLINE unsafeSplitAt #-}
+    {-# INLINE take #-}
+    {-# INLINE unsafeTake #-}
+    {-# INLINE drop #-}
+    {-# INLINE unsafeDrop #-}
+    {-# INLINE partition #-}
+    {-# INLINE uncons #-}
+    {-# INLINE unsnoc #-}
+    {-# INLINE filter #-}
+    {-# INLINE filterM #-}
+    {-# INLINE replicate #-}
+    {-# INLINE replicateM #-}
+    {-# INLINE groupBy #-}
+    {-# INLINE groupAllOn #-}
+    {-# INLINE subsequences #-}
+    {-# INLINE permutations #-}
+    {-# INLINE tailEx #-}
+    {-# INLINE initEx #-}
+    {-# INLINE unsafeTail #-}
+    {-# INLINE unsafeInit #-}
 
 defaultFind :: MonoFoldable seq => (Element seq -> Bool) -> seq -> Maybe (Element seq)
 defaultFind f = List.find f . otoList
+{-# INLINE defaultFind #-}
 
 defaultIntersperse :: IsSequence seq => Element seq -> seq -> seq
 defaultIntersperse e = fromList . List.intersperse e . otoList
+{-# INLINE defaultIntersperse #-}
 
 defaultReverse :: IsSequence seq => seq -> seq
 defaultReverse = fromList . List.reverse . otoList
+{-# INLINE defaultReverse #-}
 
 defaultSortBy :: IsSequence seq => (Element seq -> Element seq -> Ordering) -> seq -> seq
 defaultSortBy f = fromList . List.sortBy f . otoList
+{-# INLINE defaultSortBy #-}
 
 defaultCons :: IsSequence seq => Element seq -> seq -> seq
 defaultCons e = fromList . (e:) . otoList
+{-# INLINE defaultCons #-}
 
 defaultSnoc :: IsSequence seq => seq -> Element seq -> seq
 defaultSnoc seq e = fromList (otoList seq List.++ [e])
-
+{-# INLINE defaultSnoc #-}
 
 -- | like Data.List.tail, but an input of @mempty@ returns @mempty@
 tailDef :: IsSequence seq => seq -> seq
 tailDef xs = case uncons xs of
                Nothing -> mempty
                Just tuple -> snd tuple
+{-# INLINE tailDef #-}
 
 -- | like Data.List.init, but an input of @mempty@ returns @mempty@
 initDef :: IsSequence seq => seq -> seq
 initDef xs = case unsnoc xs of
                Nothing -> mempty
                Just tuple -> fst tuple
-
-
+{-# INLINE initDef #-}
 
 instance SemiSequence [a] where
     type Index [a] = Int
@@ -198,10 +226,16 @@
     sortBy = List.sortBy
     cons = (:)
     snoc = defaultSnoc
+    {-# INLINE singleton #-}
+    {-# INLINE intersperse #-}
+    {-# INLINE reverse #-}
+    {-# INLINE find #-}
+    {-# INLINE sortBy #-}
+    {-# INLINE cons #-}
+    {-# INLINE snoc #-}
 
 instance IsSequence [a] where
     fromList = id
-    {-# INLINE fromList #-}
     filter = List.filter
     filterM = Control.Monad.filterM
     break = List.break
@@ -213,6 +247,12 @@
     drop = List.drop
     uncons [] = Nothing
     uncons (x:xs) = Just (x, xs)
+    unsnoc [] = Nothing
+    unsnoc (x0:xs0) =
+        Just (loop id x0 xs0)
+      where
+        loop front x [] = (front [], x)
+        loop front x (y:z) = loop (front . (x:)) y z
     partition = List.partition
     replicate = List.replicate
     replicateM = Control.Monad.replicateM
@@ -222,6 +262,32 @@
       where
         (matches, nonMatches) = partition ((== f head) . f) tail
     groupAllOn _ [] = []
+    {-# INLINE fromList #-}
+    {-# INLINE break #-}
+    {-# INLINE span #-}
+    {-# INLINE dropWhile #-}
+    {-# INLINE takeWhile #-}
+    {-# INLINE splitAt #-}
+    {-# INLINE unsafeSplitAt #-}
+    {-# INLINE take #-}
+    {-# INLINE unsafeTake #-}
+    {-# INLINE drop #-}
+    {-# INLINE unsafeDrop #-}
+    {-# INLINE partition #-}
+    {-# INLINE uncons #-}
+    {-# INLINE unsnoc #-}
+    {-# INLINE filter #-}
+    {-# INLINE filterM #-}
+    {-# INLINE replicate #-}
+    {-# INLINE replicateM #-}
+    {-# INLINE groupBy #-}
+    {-# INLINE groupAllOn #-}
+    {-# INLINE subsequences #-}
+    {-# INLINE permutations #-}
+    {-# INLINE tailEx #-}
+    {-# INLINE initEx #-}
+    {-# INLINE unsafeTail #-}
+    {-# INLINE unsafeInit #-}
 
 instance SemiSequence (NE.NonEmpty a) where
     type Index (NE.NonEmpty a) = Int
@@ -233,6 +299,13 @@
     cons         = NE.cons
     snoc xs x    = NE.fromList $ flip snoc x $ NE.toList xs
     sortBy f     = NE.fromList . List.sortBy f . NE.toList
+    {-# INLINE singleton #-}
+    {-# INLINE intersperse #-}
+    {-# INLINE reverse #-}
+    {-# INLINE find #-}
+    {-# INLINE sortBy #-}
+    {-# INLINE cons #-}
+    {-# INLINE snoc #-}
 
 instance SemiSequence S.ByteString where
     type Index S.ByteString = Int
@@ -243,6 +316,13 @@
     cons = S.cons
     snoc = S.snoc
     sortBy = defaultSortBy
+    {-# INLINE singleton #-}
+    {-# INLINE intersperse #-}
+    {-# INLINE reverse #-}
+    {-# INLINE find #-}
+    {-# INLINE sortBy #-}
+    {-# INLINE cons #-}
+    {-# INLINE snoc #-}
 
 instance IsSequence S.ByteString where
     fromList = S.pack
@@ -266,6 +346,32 @@
     tailEx = S.tail
     initEx = S.init
     unsafeTail = SU.unsafeTail
+    {-# INLINE fromList #-}
+    {-# INLINE break #-}
+    {-# INLINE span #-}
+    {-# INLINE dropWhile #-}
+    {-# INLINE takeWhile #-}
+    {-# INLINE splitAt #-}
+    {-# INLINE unsafeSplitAt #-}
+    {-# INLINE take #-}
+    {-# INLINE unsafeTake #-}
+    {-# INLINE drop #-}
+    {-# INLINE unsafeDrop #-}
+    {-# INLINE partition #-}
+    {-# INLINE uncons #-}
+    {-# INLINE unsnoc #-}
+    {-# INLINE filter #-}
+    {-# INLINE filterM #-}
+    {-# INLINE replicate #-}
+    {-# INLINE replicateM #-}
+    {-# INLINE groupBy #-}
+    {-# INLINE groupAllOn #-}
+    {-# INLINE subsequences #-}
+    {-# INLINE permutations #-}
+    {-# INLINE tailEx #-}
+    {-# INLINE initEx #-}
+    {-# INLINE unsafeTail #-}
+    {-# INLINE unsafeInit #-}
 
 instance SemiSequence T.Text where
     type Index T.Text = Int
@@ -276,6 +382,13 @@
     cons = T.cons
     snoc = T.snoc
     sortBy = defaultSortBy
+    {-# INLINE singleton #-}
+    {-# INLINE intersperse #-}
+    {-# INLINE reverse #-}
+    {-# INLINE find #-}
+    {-# INLINE sortBy #-}
+    {-# INLINE cons #-}
+    {-# INLINE snoc #-}
 
 instance IsSequence T.Text where
     fromList = T.pack
@@ -296,6 +409,32 @@
     groupBy = T.groupBy
     tailEx = T.tail
     initEx = T.init
+    {-# INLINE fromList #-}
+    {-# INLINE break #-}
+    {-# INLINE span #-}
+    {-# INLINE dropWhile #-}
+    {-# INLINE takeWhile #-}
+    {-# INLINE splitAt #-}
+    {-# INLINE unsafeSplitAt #-}
+    {-# INLINE take #-}
+    {-# INLINE unsafeTake #-}
+    {-# INLINE drop #-}
+    {-# INLINE unsafeDrop #-}
+    {-# INLINE partition #-}
+    {-# INLINE uncons #-}
+    {-# INLINE unsnoc #-}
+    {-# INLINE filter #-}
+    {-# INLINE filterM #-}
+    {-# INLINE replicate #-}
+    {-# INLINE replicateM #-}
+    {-# INLINE groupBy #-}
+    {-# INLINE groupAllOn #-}
+    {-# INLINE subsequences #-}
+    {-# INLINE permutations #-}
+    {-# INLINE tailEx #-}
+    {-# INLINE initEx #-}
+    {-# INLINE unsafeTail #-}
+    {-# INLINE unsafeInit #-}
 
 instance SemiSequence L.ByteString where
     type Index L.ByteString = Int64
@@ -306,6 +445,13 @@
     cons = L.cons
     snoc = L.snoc
     sortBy = defaultSortBy
+    {-# INLINE singleton #-}
+    {-# INLINE intersperse #-}
+    {-# INLINE reverse #-}
+    {-# INLINE find #-}
+    {-# INLINE sortBy #-}
+    {-# INLINE cons #-}
+    {-# INLINE snoc #-}
 
 instance IsSequence L.ByteString where
     fromList = L.pack
@@ -326,6 +472,32 @@
     groupBy = L.groupBy
     tailEx = L.tail
     initEx = L.init
+    {-# INLINE fromList #-}
+    {-# INLINE break #-}
+    {-# INLINE span #-}
+    {-# INLINE dropWhile #-}
+    {-# INLINE takeWhile #-}
+    {-# INLINE splitAt #-}
+    {-# INLINE unsafeSplitAt #-}
+    {-# INLINE take #-}
+    {-# INLINE unsafeTake #-}
+    {-# INLINE drop #-}
+    {-# INLINE unsafeDrop #-}
+    {-# INLINE partition #-}
+    {-# INLINE uncons #-}
+    {-# INLINE unsnoc #-}
+    {-# INLINE filter #-}
+    {-# INLINE filterM #-}
+    {-# INLINE replicate #-}
+    {-# INLINE replicateM #-}
+    {-# INLINE groupBy #-}
+    {-# INLINE groupAllOn #-}
+    {-# INLINE subsequences #-}
+    {-# INLINE permutations #-}
+    {-# INLINE tailEx #-}
+    {-# INLINE initEx #-}
+    {-# INLINE unsafeTail #-}
+    {-# INLINE unsafeInit #-}
 
 instance SemiSequence TL.Text where
     type Index TL.Text = Int64
@@ -336,6 +508,13 @@
     cons = TL.cons
     snoc = TL.snoc
     sortBy = defaultSortBy
+    {-# INLINE singleton #-}
+    {-# INLINE intersperse #-}
+    {-# INLINE reverse #-}
+    {-# INLINE find #-}
+    {-# INLINE sortBy #-}
+    {-# INLINE cons #-}
+    {-# INLINE snoc #-}
 
 instance IsSequence TL.Text where
     fromList = TL.pack
@@ -356,6 +535,32 @@
     groupBy = TL.groupBy
     tailEx = TL.tail
     initEx = TL.init
+    {-# INLINE fromList #-}
+    {-# INLINE break #-}
+    {-# INLINE span #-}
+    {-# INLINE dropWhile #-}
+    {-# INLINE takeWhile #-}
+    {-# INLINE splitAt #-}
+    {-# INLINE unsafeSplitAt #-}
+    {-# INLINE take #-}
+    {-# INLINE unsafeTake #-}
+    {-# INLINE drop #-}
+    {-# INLINE unsafeDrop #-}
+    {-# INLINE partition #-}
+    {-# INLINE uncons #-}
+    {-# INLINE unsnoc #-}
+    {-# INLINE filter #-}
+    {-# INLINE filterM #-}
+    {-# INLINE replicate #-}
+    {-# INLINE replicateM #-}
+    {-# INLINE groupBy #-}
+    {-# INLINE groupAllOn #-}
+    {-# INLINE subsequences #-}
+    {-# INLINE permutations #-}
+    {-# INLINE tailEx #-}
+    {-# INLINE initEx #-}
+    {-# INLINE unsafeTail #-}
+    {-# INLINE unsafeInit #-}
 
 instance SemiSequence (Seq.Seq a) where
     type Index (Seq.Seq a) = Int
@@ -367,6 +572,13 @@
 
     intersperse = defaultIntersperse
     find = defaultFind
+    {-# INLINE singleton #-}
+    {-# INLINE intersperse #-}
+    {-# INLINE reverse #-}
+    {-# INLINE find #-}
+    {-# INLINE sortBy #-}
+    {-# INLINE cons #-}
+    {-# INLINE snoc #-}
 
 instance IsSequence (Seq.Seq a) where
     fromList = Seq.fromList
@@ -393,6 +605,32 @@
     --groupBy = Seq.groupBy
     tailEx = Seq.drop 1
     initEx xs = Seq.take (Seq.length xs - 1) xs
+    {-# INLINE fromList #-}
+    {-# INLINE break #-}
+    {-# INLINE span #-}
+    {-# INLINE dropWhile #-}
+    {-# INLINE takeWhile #-}
+    {-# INLINE splitAt #-}
+    {-# INLINE unsafeSplitAt #-}
+    {-# INLINE take #-}
+    {-# INLINE unsafeTake #-}
+    {-# INLINE drop #-}
+    {-# INLINE unsafeDrop #-}
+    {-# INLINE partition #-}
+    {-# INLINE uncons #-}
+    {-# INLINE unsnoc #-}
+    {-# INLINE filter #-}
+    {-# INLINE filterM #-}
+    {-# INLINE replicate #-}
+    {-# INLINE replicateM #-}
+    {-# INLINE groupBy #-}
+    {-# INLINE groupAllOn #-}
+    {-# INLINE subsequences #-}
+    {-# INLINE permutations #-}
+    {-# INLINE tailEx #-}
+    {-# INLINE initEx #-}
+    {-# INLINE unsafeTail #-}
+    {-# INLINE unsafeInit #-}
 
 instance SemiSequence (V.Vector a) where
     type Index (V.Vector a) = Int
@@ -404,6 +642,13 @@
 
     sortBy = defaultSortBy
     intersperse = defaultIntersperse
+    {-# INLINE singleton #-}
+    {-# INLINE intersperse #-}
+    {-# INLINE reverse #-}
+    {-# INLINE find #-}
+    {-# INLINE sortBy #-}
+    {-# INLINE cons #-}
+    {-# INLINE snoc #-}
 
 instance IsSequence (V.Vector a) where
     fromList = V.fromList
@@ -432,6 +677,32 @@
     initEx = V.init
     unsafeTail = V.unsafeTail
     unsafeInit = V.unsafeInit
+    {-# INLINE fromList #-}
+    {-# INLINE break #-}
+    {-# INLINE span #-}
+    {-# INLINE dropWhile #-}
+    {-# INLINE takeWhile #-}
+    {-# INLINE splitAt #-}
+    {-# INLINE unsafeSplitAt #-}
+    {-# INLINE take #-}
+    {-# INLINE unsafeTake #-}
+    {-# INLINE drop #-}
+    {-# INLINE unsafeDrop #-}
+    {-# INLINE partition #-}
+    {-# INLINE uncons #-}
+    {-# INLINE unsnoc #-}
+    {-# INLINE filter #-}
+    {-# INLINE filterM #-}
+    {-# INLINE replicate #-}
+    {-# INLINE replicateM #-}
+    {-# INLINE groupBy #-}
+    {-# INLINE groupAllOn #-}
+    {-# INLINE subsequences #-}
+    {-# INLINE permutations #-}
+    {-# INLINE tailEx #-}
+    {-# INLINE initEx #-}
+    {-# INLINE unsafeTail #-}
+    {-# INLINE unsafeInit #-}
 
 instance U.Unbox a => SemiSequence (U.Vector a) where
     type Index (U.Vector a) = Int
@@ -443,6 +714,13 @@
     cons = U.cons
     snoc = U.snoc
     sortBy = defaultSortBy
+    {-# INLINE singleton #-}
+    {-# INLINE intersperse #-}
+    {-# INLINE reverse #-}
+    {-# INLINE find #-}
+    {-# INLINE sortBy #-}
+    {-# INLINE cons #-}
+    {-# INLINE snoc #-}
 
 instance U.Unbox a => IsSequence (U.Vector a) where
     fromList = U.fromList
@@ -471,6 +749,32 @@
     initEx = U.init
     unsafeTail = U.unsafeTail
     unsafeInit = U.unsafeInit
+    {-# INLINE fromList #-}
+    {-# INLINE break #-}
+    {-# INLINE span #-}
+    {-# INLINE dropWhile #-}
+    {-# INLINE takeWhile #-}
+    {-# INLINE splitAt #-}
+    {-# INLINE unsafeSplitAt #-}
+    {-# INLINE take #-}
+    {-# INLINE unsafeTake #-}
+    {-# INLINE drop #-}
+    {-# INLINE unsafeDrop #-}
+    {-# INLINE partition #-}
+    {-# INLINE uncons #-}
+    {-# INLINE unsnoc #-}
+    {-# INLINE filter #-}
+    {-# INLINE filterM #-}
+    {-# INLINE replicate #-}
+    {-# INLINE replicateM #-}
+    {-# INLINE groupBy #-}
+    {-# INLINE groupAllOn #-}
+    {-# INLINE subsequences #-}
+    {-# INLINE permutations #-}
+    {-# INLINE tailEx #-}
+    {-# INLINE initEx #-}
+    {-# INLINE unsafeTail #-}
+    {-# INLINE unsafeInit #-}
 
 instance VS.Storable a => SemiSequence (VS.Vector a) where
     type Index (VS.Vector a) = Int
@@ -482,6 +786,13 @@
 
     intersperse = defaultIntersperse
     sortBy = defaultSortBy
+    {-# INLINE singleton #-}
+    {-# INLINE intersperse #-}
+    {-# INLINE reverse #-}
+    {-# INLINE find #-}
+    {-# INLINE sortBy #-}
+    {-# INLINE cons #-}
+    {-# INLINE snoc #-}
 
 instance VS.Storable a => IsSequence (VS.Vector a) where
     fromList = VS.fromList
@@ -510,14 +821,40 @@
     initEx = VS.init
     unsafeTail = VS.unsafeTail
     unsafeInit = VS.unsafeInit
+    {-# INLINE fromList #-}
+    {-# INLINE break #-}
+    {-# INLINE span #-}
+    {-# INLINE dropWhile #-}
+    {-# INLINE takeWhile #-}
+    {-# INLINE splitAt #-}
+    {-# INLINE unsafeSplitAt #-}
+    {-# INLINE take #-}
+    {-# INLINE unsafeTake #-}
+    {-# INLINE drop #-}
+    {-# INLINE unsafeDrop #-}
+    {-# INLINE partition #-}
+    {-# INLINE uncons #-}
+    {-# INLINE unsnoc #-}
+    {-# INLINE filter #-}
+    {-# INLINE filterM #-}
+    {-# INLINE replicate #-}
+    {-# INLINE replicateM #-}
+    {-# INLINE groupBy #-}
+    {-# INLINE groupAllOn #-}
+    {-# INLINE subsequences #-}
+    {-# INLINE permutations #-}
+    {-# INLINE tailEx #-}
+    {-# INLINE initEx #-}
+    {-# INLINE unsafeTail #-}
+    {-# INLINE unsafeInit #-}
 
 class (IsSequence seq, Eq (Element seq)) => EqSequence seq where
     stripPrefix :: seq -> seq -> Maybe seq
     stripPrefix x y = fmap fromList (otoList x `stripPrefix` otoList y)
-    
+
     isPrefixOf :: seq -> seq -> Bool
     isPrefixOf x y = otoList x `isPrefixOf` otoList y
-    
+
     stripSuffix :: seq -> seq -> Maybe seq
     stripSuffix x y = fmap fromList (otoList x `stripSuffix` otoList y)
 
@@ -529,8 +866,8 @@
 
     group :: seq -> [seq]
     group = groupBy (==)
-    
-    -- | Similar to standard 'group', but operates on the whole collection, 
+
+    -- | Similar to standard 'group', but operates on the whole collection,
     -- not just the consecutive items.
     groupAll :: seq -> [seq]
     groupAll = groupAllOn id
@@ -540,6 +877,15 @@
 
     notElem :: Element seq -> seq -> Bool
     notElem e = List.notElem e . otoList
+    {-# INLINE stripPrefix #-}
+    {-# INLINE isPrefixOf #-}
+    {-# INLINE stripSuffix #-}
+    {-# INLINE isSuffixOf #-}
+    {-# INLINE isInfixOf #-}
+    {-# INLINE group #-}
+    {-# INLINE groupAll #-}
+    {-# INLINE elem #-}
+    {-# INLINE notElem #-}
 
 instance Eq a => EqSequence [a] where
     stripPrefix = List.stripPrefix
@@ -550,6 +896,15 @@
     group = List.group
     elem = List.elem
     notElem = List.notElem
+    {-# INLINE stripPrefix #-}
+    {-# INLINE isPrefixOf #-}
+    {-# INLINE stripSuffix #-}
+    {-# INLINE isSuffixOf #-}
+    {-# INLINE isInfixOf #-}
+    {-# INLINE group #-}
+    {-# INLINE groupAll #-}
+    {-# INLINE elem #-}
+    {-# INLINE notElem #-}
 
 instance EqSequence S.ByteString where
     stripPrefix x y
@@ -564,6 +919,15 @@
     group = S.group
     elem = S.elem
     notElem = S.notElem
+    {-# INLINE stripPrefix #-}
+    {-# INLINE isPrefixOf #-}
+    {-# INLINE stripSuffix #-}
+    {-# INLINE isSuffixOf #-}
+    {-# INLINE isInfixOf #-}
+    {-# INLINE group #-}
+    {-# INLINE groupAll #-}
+    {-# INLINE elem #-}
+    {-# INLINE notElem #-}
 
 instance EqSequence L.ByteString where
     stripPrefix x y
@@ -578,6 +942,15 @@
     group = L.group
     elem = L.elem
     notElem = L.notElem
+    {-# INLINE stripPrefix #-}
+    {-# INLINE isPrefixOf #-}
+    {-# INLINE stripSuffix #-}
+    {-# INLINE isSuffixOf #-}
+    {-# INLINE isInfixOf #-}
+    {-# INLINE group #-}
+    {-# INLINE groupAll #-}
+    {-# INLINE elem #-}
+    {-# INLINE notElem #-}
 
 instance EqSequence T.Text where
     stripPrefix = T.stripPrefix
@@ -586,6 +959,15 @@
     isSuffixOf = T.isSuffixOf
     isInfixOf = T.isInfixOf
     group = T.group
+    {-# INLINE stripPrefix #-}
+    {-# INLINE isPrefixOf #-}
+    {-# INLINE stripSuffix #-}
+    {-# INLINE isSuffixOf #-}
+    {-# INLINE isInfixOf #-}
+    {-# INLINE group #-}
+    {-# INLINE groupAll #-}
+    {-# INLINE elem #-}
+    {-# INLINE notElem #-}
 
 instance EqSequence TL.Text where
     stripPrefix = TL.stripPrefix
@@ -594,6 +976,15 @@
     isSuffixOf = TL.isSuffixOf
     isInfixOf = TL.isInfixOf
     group = TL.group
+    {-# INLINE stripPrefix #-}
+    {-# INLINE isPrefixOf #-}
+    {-# INLINE stripSuffix #-}
+    {-# INLINE isSuffixOf #-}
+    {-# INLINE isInfixOf #-}
+    {-# INLINE group #-}
+    {-# INLINE groupAll #-}
+    {-# INLINE elem #-}
+    {-# INLINE notElem #-}
 
 instance Eq a => EqSequence (Seq.Seq a)
 instance Eq a => EqSequence (V.Vector a)
@@ -603,12 +994,15 @@
 class (EqSequence seq, MonoFoldableOrd seq) => OrdSequence seq where
     sort :: seq -> seq
     sort = fromList . List.sort . otoList
+    {-# INLINE sort #-}
 
 instance Ord a => OrdSequence [a] where
     sort = List.sort
+    {-# INLINE sort #-}
 
 instance OrdSequence S.ByteString where
     sort = S.sort
+    {-# INLINE sort #-}
 
 instance OrdSequence L.ByteString
 instance OrdSequence T.Text
@@ -635,6 +1029,7 @@
 
     breakWord :: t -> (t, t)
     breakWord = fmap (dropWhile isSpace) . break isSpace
+    {-# INLINE breakWord #-}
 
     breakLine :: t -> (t, t)
     breakLine =
@@ -653,6 +1048,13 @@
     toLower = TL.unpack . TL.toLower . TL.pack
     toUpper = TL.unpack . TL.toUpper . TL.pack
     toCaseFold = TL.unpack . TL.toCaseFold . TL.pack
+    {-# INLINE words #-}
+    {-# INLINE unwords #-}
+    {-# INLINE lines #-}
+    {-# INLINE unlines #-}
+    {-# INLINE toLower #-}
+    {-# INLINE toUpper #-}
+    {-# INLINE toCaseFold #-}
 
 instance Textual T.Text where
     words = T.words
@@ -662,6 +1064,13 @@
     toLower = T.toLower
     toUpper = T.toUpper
     toCaseFold = T.toCaseFold
+    {-# INLINE words #-}
+    {-# INLINE unwords #-}
+    {-# INLINE lines #-}
+    {-# INLINE unlines #-}
+    {-# INLINE toLower #-}
+    {-# INLINE toUpper #-}
+    {-# INLINE toCaseFold #-}
 
 instance Textual TL.Text where
     words = TL.words
@@ -671,3 +1080,10 @@
     toLower = TL.toLower
     toUpper = TL.toUpper
     toCaseFold = TL.toCaseFold
+    {-# INLINE words #-}
+    {-# INLINE unwords #-}
+    {-# INLINE lines #-}
+    {-# INLINE unlines #-}
+    {-# INLINE toLower #-}
+    {-# INLINE toUpper #-}
+    {-# INLINE toCaseFold #-}
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -58,6 +58,19 @@
     describe "groupAll" $ do
         it "list" $ groupAll ("abcabcabc" :: String) == ["aaa", "bbb", "ccc"]
         it "Text" $ groupAll ("abcabcabc" :: Text) == ["aaa", "bbb", "ccc"]
+    describe "unsnoc" $ do
+        let test name dummy = prop name $ \xs ->
+                let seq' = fromList xs `asTypeOf` dummy
+                 in case (unsnoc seq', onull seq', onull xs) of
+                        (Nothing, True, True) -> return ()
+                        (Just (y, z), False, False) -> do
+                            (y SG.<> singleton z) `shouldBe` seq'
+                            snoc y z `shouldBe` seq'
+                            otoList (snoc y z) `shouldBe` xs
+                        x -> Prelude.error $ show x
+        test "list" ([] :: [Int])
+        test "Text" ("" :: Text)
+        test "lazy ByteString" L.empty
     describe "groupAllOn" $ do
         it "list" $ groupAllOn (`mod` 3) ([1..9] :: [Int]) == [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
     describe "breakWord" $ do
