diff --git a/folds-common.cabal b/folds-common.cabal
--- a/folds-common.cabal
+++ b/folds-common.cabal
@@ -1,5 +1,5 @@
 name:                folds-common
-version:             0.1.1.0
+version:             0.2.0.0
 synopsis:            A playground of common folds for folds
 description:         In an effort to make @folds@ a more usable package this
                      package provides a battery of common folds. These can be
@@ -20,17 +20,39 @@
   exposed-modules:     Data.Fold.Common
                      , Data.Fold.Common.L'
                      , Data.Fold.Common.M
+                     , Data.Fold.Common.R
   build-depends:       base >=4.0 && <5
                      , containers >= 0.5
                      , folds >= 0.5
   hs-source-dirs:      src
   default-language:    Haskell2010
 
-Test-Suite properties
+Test-Suite left-properties
   type:               exitcode-stdio-1.0
-  main-is:            Main.hs
+  main-is:            L'.hs
   hs-source-dirs:     test
   build-depends:      folds-common
+                    , containers
+                    , tasty
+                    , tasty-quickcheck
+                    , base > 4.0 && < 5
+  default-language:    Haskell2010
+Test-Suite monoid-properties
+  type:               exitcode-stdio-1.0
+  main-is:            M.hs
+  hs-source-dirs:     test
+  build-depends:      folds-common
+                    , containers
+                    , tasty
+                    , tasty-quickcheck
+                    , base > 4.0 && < 5
+  default-language:    Haskell2010
+Test-Suite right-properties
+  type:               exitcode-stdio-1.0
+  main-is:            R.hs
+  hs-source-dirs:     test
+  build-depends:      folds-common
+                    , containers
                     , tasty
                     , tasty-quickcheck
                     , base > 4.0 && < 5
diff --git a/src/Data/Fold/Common.hs b/src/Data/Fold/Common.hs
--- a/src/Data/Fold/Common.hs
+++ b/src/Data/Fold/Common.hs
@@ -1,9 +1,5 @@
--- | This module exports a few common folds. Some of these are defined
--- as @L'@ folds if they cannot short-circuit. The rest are defined
--- as monoidal folds. Since you may want to combine a monoidal and
--- strict left fold, 'strictify' is an operation that drops laziness
--- and reassociates an 'M'. This may result in a slow down in
--- performance though.
+{-# LANGUAGE Safe #-}
+-- | This module exports a bunch of common folds.
 --
 -- For the classic example
 --
@@ -16,12 +12,51 @@
 -- > main :: IO ()
 -- > main = print $ C.run [1 .. 10000000] avg
 --
--- This will run in constant memory as we'd hope.
+-- This will run in constant memory as we'd hope.  In general the
+-- rules for keeping memory usage low while using @folds@ are
 --
+--  * Don't try to consume a left fold lazily
+--  * Don't try to consume a right fold strictly
+--  * Never use '>>='
+--  * Never use 'prefix' on right folds
+--  * Never use 'postfix' on left folds
+--
+-- Also note that monoidal folds can be combined with strict left ones
+-- with 'strictify'.
 module Data.Fold.Common
        ( module Data.Fold
-       , module Data.Fold.Common.L'
-       , module Data.Fold.Common.M) where
+         -- * Left Folds
+       , sum
+       , product
+       , count
+       , mconcat
+       , minimum
+       , maximum
+       , nub
+       , slowNub
+       , intoSet
+       , last
+       , nth
+         -- * Monoidal Folds
+       , any
+       , all
+       , and
+       , or
+       , elem
+       , notElem
+       , find
+       , head
+       , null
+       , strictify
+         -- * Right Folds
+       , intoList
+       , take
+       , drop
+       , indexOf
+       , chunk
+       , concat) where
+import Prelude ()
 import Data.Fold
 import Data.Fold.Common.L'
 import Data.Fold.Common.M
+import Data.Fold.Common.R
diff --git a/src/Data/Fold/Common/L'.hs b/src/Data/Fold/Common/L'.hs
--- a/src/Data/Fold/Common/L'.hs
+++ b/src/Data/Fold/Common/L'.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE Safe #-}
 -- | A collection of common left folds. Note that all of these are
 -- strict and do not short circuit. These are useful for operations
 -- that require inspecting the entire list to calculate the final
@@ -92,9 +93,10 @@
 -- >>> run [1, 2, 1] slowNub
 -- [1, 2]
 slowNub :: Eq a => L' a [a]
-slowNub = L' id step []
-  where step as a | a `elem` as = as
-                  | otherwise = a : as
+slowNub = L' (\(Pair' _ xs) -> xs []) step (Pair' [] id)
+  where step (Pair' set as) a | a `elem` set = Pair' set as
+                              | otherwise = Pair' (a : set) (as . (a :))
+        -- Note that this is just a subset of Diff lists
 
 -- | Collect all members into a @Set@.
 --
@@ -121,8 +123,9 @@
 --
 -- >>> run [1 .. 10] (nth 20)
 -- Nothing
-nth :: (Eq b, Num b) => b -> L' a (Maybe a)
+nth :: (Eq b, Ord b, Num b) => b -> L' a (Maybe a)
 nth b = L' (\(Pair' e _) -> maybe' Nothing Just e) step (Pair' Nothing' b)
   where step st@(Pair' (Just' _) _) _ = st
+        step (Pair' _ n) _ | n < 0 = Pair' Nothing' n
         step (Pair' _ 0) a = Pair' (Just' a) 0
         step (Pair' _ n) _ = Pair' Nothing' (n - 1)
diff --git a/src/Data/Fold/Common/M.hs b/src/Data/Fold/Common/M.hs
--- a/src/Data/Fold/Common/M.hs
+++ b/src/Data/Fold/Common/M.hs
@@ -1,11 +1,11 @@
--- | A collection of right folds. These are all short circuiting and
+{-# LANGUAGE Safe #-}
+-- | A collection of monoidal folds. These are all short circuiting and
 -- are designed to handle certain infinite cases properly. These are
 -- useful for operations which don't require the full list to
 -- calculate the output.
 module Data.Fold.Common.M where
 import Prelude hiding (any, all)
 import Data.Fold
-import Data.Fold.Internal hiding (First)
 import Data.Monoid
 
 -- | Check that if predicate holds for any inputs to the fold.
@@ -26,7 +26,7 @@
 -- >>> run [1, 2, 3, 4] (all (> 1))
 -- False
 all :: (a -> Bool) -> M a Bool
-all p = M getAll (All . p) (<>) (All False)
+all p = M getAll (All . p) (<>) (All True)
 
 -- | Check whether all elements are 'True'.
 --
@@ -47,6 +47,25 @@
 or :: M Bool Bool
 or = any id
 
+-- | Check whether an element is fed into the fold.
+--
+-- >>> run [1, 2, 3] (elem 3)
+-- True
+--
+-- >>> run [] (elem 1)
+-- False
+elem :: Eq a => a -> M a Bool
+elem a = any (== a)
+
+-- | Check whther an element isn't fed into the fold.
+-- >>> run [1, 2, 3] (notElem 3)
+-- False
+--
+-- >>> run [] (notElem 1)
+-- True
+notElem :: Eq a => a -> M a Bool
+notElem a = all (/= a)
+
 -- | Find the first element for which a predicate holds.
 --
 -- >>> run [1, 2, 3, 4] (find even)
@@ -58,20 +77,6 @@
 find p = M getFirst to (<>) (First Nothing)
   where to a = First $ if p a then Just a else Nothing
 
--- | Find the first index for which a predicate holds.
---
--- >>> run [1, 2, 3, 4] (indexOf (== 4))
--- Just 3
---
--- >>> run [1, 2, 3, 4] (indexOf (> 4))
--- Nothing
-indexOf :: Enum e => (a -> Bool) -> M a (Maybe e)
-indexOf p = M (maybe' Nothing Just) to m Nothing'
-  where to a = if p a then Just' (toEnum 0) else Nothing'
-        m (Just' a) _ = Just' (succ a)
-        m _ (Just' a) = Just' (succ a)
-        m _ _ = Nothing'
-
 -- | Grab the first inputted element.
 --
 -- >>> run [1 ..] head
@@ -82,6 +87,16 @@
 head :: M a (Maybe a)
 head = M getFirst (First . Just) (<>) (First Nothing)
 
+-- | Check whether a fold was fed any elements.
+--
+-- >>> run [] null
+-- True
+--
+-- >>> run [1..] null
+-- False
+null :: M a Bool
+null = M id (const False) (&&) True
+
 -- | Occasionally we want to use a short-circuiting fold with other,
 -- nonlazy folds. This function drops laziness on the floor for a @L'@
 -- fold. This is dangerous because it can potentially effect
@@ -93,8 +108,8 @@
 -- >>> run (repeat False) (strictify and)
 -- ... diverges ...
 --
--- This means it is only advisable to use when combining a monoidal
--- fold with something that requires left folding.
+-- This is generally an advantage when we want to combine a monoidal
+-- fold with a left one.
 --
 -- >>> run [1.0, 2, 3, 4] $ (/) <$> strictify head <*> maximum
 -- 0.25
diff --git a/src/Data/Fold/Common/R.hs b/src/Data/Fold/Common/R.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Fold/Common/R.hs
@@ -0,0 +1,93 @@
+{-# LANGUAGE Safe #-}
+-- | A series of common right folds. These tend to be list centric
+-- since since lists provide such a lousy monoid.
+module Data.Fold.Common.R where
+import Data.Fold
+import Data.Fold.Internal
+
+-- | An extremely boring fold. You can almost view this as an identity
+-- fold across lists.
+--
+-- >>> run [1 .. 10] intoLists
+-- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+intoList :: R a [a]
+intoList = R id (:) []
+
+-- | Take the first @n@ inputs to the fold. If less then @n@ inputs
+-- are fed in total then take as many as possible.
+--
+-- >>> run [1 .. 10] (take 3)
+-- [1, 2, 3]
+--
+-- >>> run [1, 2, 3] (take 100)
+-- [1, 2, 3]
+take :: (Eq b, Ord b, Num b) => b -> R a [a]
+take b = R ($ b) step (\_ -> [])
+  where step x xs n | n <= 0 = []
+                    | otherwise = x : xs (n - 1)
+
+-- | Drop the first @n@ items. If less then @n@ items are supplied
+-- then return the empty list.
+--
+-- >>> run [1, 2, 3] (drop 1)
+-- [2, 3]
+--
+-- >>> run [1, 2, 3] (drop 100)
+-- []
+drop :: (Eq b, Ord b, Num b) => b -> R a [a]
+drop b = R ($ b) step (\_ -> [])
+  where step x xs n | n <= 0 = x : xs 0
+                    | otherwise = xs (n - 1)
+        -- Note, this costs an integer comparison + thunks along the
+        -- list. Is this really OK? It's still perfectly lazy at
+        -- least.
+
+-- | Find the first index for which a predicate holds.
+--
+-- >>> run [1, 2, 3, 4] (indexOf (== 4))
+-- Just 3
+--
+-- >>> run [1, 2, 3, 4] (indexOf (> 4))
+-- Nothing
+indexOf :: Enum e => (a -> Bool) -> R a (Maybe e)
+indexOf p = R (maybe' Nothing Just) step Nothing'
+  where step a _ | p a = Just' (toEnum 0)
+        step _ Nothing' = Nothing'
+        step _ (Just' a) = Just' (succ a)
+
+
+-- | Chunk the input into partitions according to a function. While
+-- the values from the function are equal elements are collected into
+-- a chunk. Note that partitioning according to a predicate is just a
+-- special case of this.
+--
+-- >>> run [1, 1, 2, 3] (chunk id)
+-- [[1, 1], [2], [3]]
+--
+-- >>> run [1, -1, 2, 1] (chunk abs)
+-- [[1, -1], 2, [1]]
+--
+-- >>> run [1, 2, 4, 6, 5] (chunk even)
+-- [[1], [2, 4, 6], 5]
+chunk :: (Show b, Eq b) => (a -> b) -> R a [[a]]
+chunk f = R (\(Pair' _ xs) -> xs) step (Pair' Nothing' [])
+  where step a (Pair' Nothing' l) = Pair' (Just' $ f a) [[a]]
+        step a (Pair' (Just' b) (as : ass)) =
+          let b' = f a
+          in if b == b'
+             then Pair' (Just' b') ((a : as) : ass)
+             else Pair' (Just' b') ([a] : as : ass)
+
+-- | Lazily produce a flattened list of the inputted lists.
+--
+-- >>> run [[1], [2], [3]] concat
+-- [1, 2, 3]
+--
+-- >>> head $ run (map return [1..]) concat
+-- 1
+--
+-- Note: The right fold ensures that all applications of '++'
+-- associate to the right. This makes this fold ideal for streaming
+-- but slow when completely forced.
+concat :: R [a] [a]
+concat = R id (++) []
diff --git a/test/L'.hs b/test/L'.hs
new file mode 100644
--- /dev/null
+++ b/test/L'.hs
@@ -0,0 +1,74 @@
+module Main where
+import qualified Data.Fold.Common as C
+import Data.Monoid
+import Data.List
+import qualified Data.Set as S
+import Test.Tasty
+import Test.Tasty.QuickCheck
+
+propSum :: TestTree
+propSum = testProperty "Sum Works"
+          $ \l -> C.run l C.sum == (sum l :: Int)
+
+propProduct :: TestTree
+propProduct = testProperty "Product Works"
+              $ \l -> C.run l C.product == (product l :: Int)
+
+propCount :: TestTree
+propCount = testProperty "Count Works"
+            $ \l -> C.run l C.count == length (l :: [Int])
+
+propMconcat :: TestTree
+propMconcat = testProperty "Mconcat Works"
+              $ \l -> C.run (map Sum l) C.mconcat
+                      == mconcat (map Sum l :: [Sum Int])
+
+propMinimum :: TestTree
+propMinimum = testProperty "Minimum Works"
+          $ \l -> C.run l C.minimum == mminimum (l :: [Int])
+  where mminimum [] = Nothing
+        mminimum xs = Just (minimum xs)
+
+propMaximum :: TestTree
+propMaximum = testProperty "Maximum Works"
+          $ \l -> C.run l C.maximum == mmaximum (l :: [Int])
+  where mmaximum [] = Nothing
+        mmaximum xs = Just (maximum xs)
+
+propNub :: TestTree
+propNub = testProperty "Nub Works"
+          $ \l -> C.run l C.nub == nub (l :: [Int])
+
+propSlowNub :: TestTree
+propSlowNub = testProperty "SlowNub Works"
+          $ \l -> C.run l C.slowNub == nub (l :: [Int])
+
+propIntoSet :: TestTree
+propIntoSet = testProperty "IntoSet Works"
+          $ \l -> C.run l C.intoSet == S.fromList (l :: [Int])
+
+
+propLast :: TestTree
+propLast = testProperty "Last works"
+           $ \l -> C.run l C.last == (mlast l :: Maybe Int)
+  where mlast [] = Nothing
+        mlast xs = Just (last xs)
+
+propNth :: TestTree
+propNth = testProperty "Nth works"
+           $ \i l -> C.run l (C.nth i) == (nth i l :: Maybe Int)
+  where nth n xs | length xs <= n || n < 0 = Nothing
+        nth n xs = Just (xs !! n)
+
+main :: IO ()
+main = defaultMain $ testGroup "Left Folds" [ propSum
+                                            , propProduct
+                                            , propCount
+                                            , propMconcat
+                                            , propMinimum
+                                            , propMaximum
+                                            , propNub
+                                            , propSlowNub
+                                            , propIntoSet
+                                            , propLast
+                                            , propNth]
diff --git a/test/M.hs b/test/M.hs
new file mode 100644
--- /dev/null
+++ b/test/M.hs
@@ -0,0 +1,64 @@
+module Main where
+import qualified Data.Fold.Common as C
+import Data.List
+import Test.Tasty
+import Test.Tasty.QuickCheck
+
+propAny :: TestTree
+propAny = testProperty "Any Works"
+          $ \l -> C.run l (C.any even) == any even (l :: [Int])
+
+propAll :: TestTree
+propAll = testProperty "All Works"
+          $ \l -> C.run l (C.all even) == all even (l :: [Int])
+
+propAnd :: TestTree
+propAnd = testProperty "And Works"
+          $ \l -> C.run l C.and == and (l :: [Bool])
+
+propOr :: TestTree
+propOr = testProperty "Or Works"
+         $ \l -> C.run l C.or == or (l :: [Bool])
+
+propElem :: TestTree
+propElem = testProperty "Elem Works"
+          $ \l i -> C.run l (C.elem i) == elem i (l :: [Int])
+
+propNotElem :: TestTree
+propNotElem = testProperty "NotElem Works"
+          $ \l i -> C.run l (C.notElem i) == notElem i (l :: [Int])
+
+
+propFind :: TestTree
+propFind = testProperty "Find Works"
+           $ \l -> C.run l (C.find even) == find even (l :: [Int])
+
+propNull :: TestTree
+propNull = testProperty "Null Works"
+           $ \l -> C.run l C.null == null (l :: [Int])
+
+propHead :: TestTree
+propHead = testProperty "Head Works"
+           $ \l -> C.run l C.head == mhead (l :: [Int])
+  where mhead [] = Nothing
+        mhead (x : xs) = Just x
+
+propStrictify :: TestTree
+propStrictify = testGroup "Strictify Works" [ s "any" $ C.any even
+                                            , s "all" $ C.all even
+                                            , s "find" $ C.find even]
+  where s name f =
+          testProperty name
+          $ \l -> C.run (l :: [Int]) f == C.run l (C.strictify f)
+
+main :: IO ()
+main = defaultMain $ testGroup "Monoidal Folds" [ propAny
+                                                , propAll
+                                                , propAnd
+                                                , propOr
+                                                , propElem
+                                                , propNotElem
+                                                , propFind
+                                                , propHead
+                                                , propNull
+                                                , propStrictify]
diff --git a/test/Main.hs b/test/Main.hs
deleted file mode 100644
--- a/test/Main.hs
+++ /dev/null
@@ -1,63 +0,0 @@
-module Main where
-import qualified Data.Fold.Common as C
-import Data.List
-import Test.Tasty
-import Test.Tasty.QuickCheck
-
-
-propSum :: TestTree
-propSum = testProperty "Sum Works"
-          $ \l -> C.run l C.sum == (sum l :: Int)
-
-propProduct :: TestTree
-propProduct = testProperty "Product Works"
-              $ \l -> C.run l C.product == (product l :: Int)
-
-propCount :: TestTree
-propCount = testProperty "Count Works"
-            $ \l -> C.run l C.count == length (l :: [Int])
-
-propNub :: TestTree
-propNub = testProperty "Nub Works"
-          $ \l -> C.run l C.nub == nub (l :: [Int])
-
-leftFolds :: TestTree
-leftFolds = testGroup "Left Folds" [ propSum
-                                   , propProduct
-                                   , propCount
-                                   , propNub]
-
-propAny :: TestTree
-propAny = testProperty "Any Works"
-          $ \l -> C.run l (C.any even) == any even (l :: [Int])
-
-propAll :: TestTree
-propAll = testProperty "All Works"
-          $ \l -> C.run l (C.all even) == all even (l :: [Int])
-
-propFind :: TestTree
-propFind = testProperty "Find Works"
-           $ \l -> C.run l (C.find even) == find even (l :: [Int])
-
-propIndexOf :: TestTree
-propIndexOf = testProperty "IndexOf Works"
-              $ \l -> C.run l (C.indexOf even) == findIndex even (l :: [Int])
-
-propStrictify :: TestTree
-propStrictify = testGroup "Strictify Works" [ s "any" $ C.any even
-                                            , s "all" $ C.all even
-                                            , s "find" $ C.find even]
-  where s name f =
-          testProperty name
-          $ \l -> C.run (l :: [Int]) f == C.run l (C.strictify f)
-
-
-monoidFolds :: TestTree
-monoidFolds = testGroup "Monoidal Folds" [ propAny
-                                         , propAll
-                                         , propFind
-                                         , propIndexOf
-                                         , propStrictify]
-
-main :: IO ()
-main = defaultMain $ testGroup "Folds" [leftFolds]
diff --git a/test/R.hs b/test/R.hs
new file mode 100644
--- /dev/null
+++ b/test/R.hs
@@ -0,0 +1,42 @@
+module Main where
+import qualified Data.Fold.Common as C
+import Data.List
+import Test.Tasty
+import Test.Tasty.QuickCheck
+
+
+propIntoList :: TestTree
+propIntoList = testProperty "intoList Works"
+               $ \l -> C.run l C.intoList == (l :: [Int])
+
+propTake :: TestTree
+propTake = testProperty "Take Works"
+           $ \l i -> C.run l (C.take i) == (take i l :: [Int])
+
+propDrop :: TestTree
+propDrop = testProperty "Drop Works"
+           $ \l i -> C.run l (C.drop i) == (drop i l :: [Int])
+
+
+propIndexOf :: TestTree
+propIndexOf = testProperty "IndexOf Works"
+              $ \l -> C.run l (C.indexOf even) == findIndex even (l :: [Int])
+
+propChunk :: TestTree
+propChunk = testProperty "Chunk Works"
+            $ \l -> C.run l (C.chunk id) == chunk (l :: [Int])
+  where chunk [] = []
+        chunk (x : xs) =
+          (x : takeWhile (== x) xs) : chunk (dropWhile (== x) xs)
+
+propConcat :: TestTree
+propConcat = testProperty "Concat Works"
+              $ \l -> C.run l C.concat == concat (l :: [[Int]])
+
+main :: IO ()
+main = defaultMain $ testGroup "Right Folds" [ propIntoList
+                                             , propTake
+                                             , propDrop
+                                             , propIndexOf
+                                             , propChunk
+                                             , propConcat]
