diff --git a/LICENCE b/LICENCE
new file mode 100644
--- /dev/null
+++ b/LICENCE
@@ -0,0 +1,31 @@
+Copyright (c) 2017, Commonwealth Scientific and Industrial Research Organisation
+(CSIRO) ABN 41 687 119 230.
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of QFPL nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,3 +1,8 @@
+0.2.0
+
+* Refactoring with lots of changes to data types.
+* Introduce nix for building.
+
 0.1.2
 
 * Add instance of `Wrapped` and `Swapped`.
diff --git a/etc/LICENCE b/etc/LICENCE
deleted file mode 100644
--- a/etc/LICENCE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright 2013-2014 Tony Morris
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-3. Neither the name of the author nor the names of his contributors
-   may be used to endorse or promote products derived from this software
-   without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
diff --git a/separated.cabal b/separated.cabal
--- a/separated.cabal
+++ b/separated.cabal
@@ -1,13 +1,16 @@
 name:               separated
-version:            0.1.2
+version:            0.2.0
 license:            BSD3
-license-File:       etc/LICENCE
+license-File:       LICENCE
 author:             Tony Morris <ʇǝu˙sıɹɹoɯʇ@ןןǝʞsɐɥ>
 maintainer:         Tony Morris
 copyright:          Copyright (c) 2016, Commonwealth Scientific and Industrial Research Organisation (CSIRO) ABN 41 687 119 230.
 synopsis:           A data type with elements separated by values
 category:           Data
-description:        A data type with elements separated by values
+description:       
+  <<http://i.imgur.com/0h9dFhl.png>>
+  .
+   A data type with elements separated by values
 homepage:           https://github.com/data61/separated
 bug-reports:        https://github.com/data61/separated/issues
 cabal-version:      >= 1.10
@@ -31,7 +34,6 @@
                     , semigroups >= 0.9
                     , semigroupoids >= 4.0
                     , bifunctors >= 4.0
-                    , papa
                     
   ghc-options:
                     -Wall
@@ -44,8 +46,6 @@
 
   exposed-modules:
                     Data.Separated
-                    Data.Separated.Separated
-                    Data.Separated.SeparatedCons
 
 test-suite doctests
   type:
diff --git a/src/Data/Separated.hs b/src/Data/Separated.hs
--- a/src/Data/Separated.hs
+++ b/src/Data/Separated.hs
@@ -1,8 +1,848 @@
 {-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE RankNTypes #-}
 
 module Data.Separated(
-  module S
+-- * Data types
+  Separated(..)
+, Separated1(..)
+, Pesarated(..)
+, Pesarated1(..)
+-- * Iso
+, separated
+, separated1
+, pesarated
+, pesarated1
+-- * Viewing
+, HasHead(..)
+, HasTail(..)
+-- * Constructing
+, Separated1Single(..)
+, Pesarated1Single(..)
+, Construct(..)
+, SeparatedCons(..)
+, PesaratedCons(..)
+-- * Appending
+, Appends(..)
+-- * Alternating
+, separatedBy
+, separatedBy1
+, pesaratedBy
+, pesaratedBy1
 ) where
 
-import Data.Separated.Separated as S
-import Data.Separated.SeparatedCons as S
+import Control.Applicative(Applicative((<*>), pure), Alternative(many))
+import Control.Category(Category((.), id))
+import Control.Lens(Swapped(swapped), Iso, Lens, iso, from, (#), (^.), _1, _2, makeWrapped, _Wrapped)
+import Data.Bifoldable(Bifoldable(bifoldr))
+import Data.Bifunctor(Bifunctor(bimap), first)
+import Data.Bitraversable(Bitraversable(bitraverse))
+import Data.Eq(Eq)
+import Data.Foldable(foldr)
+import Data.Functor(Functor(fmap), (<$>))
+import Data.Functor.Apply as Apply(Apply((<.>)))
+import Data.List(intercalate, zipWith, repeat)
+import Data.Monoid(Monoid(mappend, mempty))
+import Data.Ord(Ord)
+import Data.Semigroup as Semigroup(Semigroup((<>)))
+import Data.String(String)
+import Data.Traversable(traverse)
+import Data.Tuple(uncurry)
+import Prelude(Show(show))
+
+-- $setup
+-- >>> :set -XNoImplicitPrelude
+-- >>> :set -XFlexibleContexts
+-- >>> import Control.Lens(set)
+-- >>> import Control.Monad(return)
+-- >>> import Data.Char(toUpper)
+-- >>> import Data.Either(isLeft)
+-- >>> import Prelude hiding (id, (.))
+-- >>> import Text.Parsec(parse, char, digit)
+-- >>> import Test.QuickCheck(Arbitrary(..))
+-- >>> instance (Arbitrary s, Arbitrary a) => Arbitrary (Separated s a) where arbitrary = fmap (^. separated) arbitrary
+-- >>> instance (Arbitrary a, Arbitrary s) => Arbitrary (Separated1 s a) where arbitrary = do a <- arbitrary; x <- arbitrary; return ((a, x) ^. separated1)
+-- >>> instance (Arbitrary s, Arbitrary a) => Arbitrary (Pesarated s a) where arbitrary = fmap (^. pesarated) arbitrary
+-- >>> instance (Arbitrary s, Arbitrary a) => Arbitrary (Pesarated1 s a) where arbitrary = fmap (^. pesarated1) arbitrary
+-- >>> let emptySeparated :: Separated s a; emptySeparated = empty
+-- >>> let emptyPesarated :: Pesarated s a; emptyPesarated = empty
+
+-- | A list of pairs of separator and value. Separated by @a@ in values @b@.
+-- There are an even number of separators as there are values.
+newtype Separated a b =
+  Separated [(a, b)]
+  deriving (Eq, Ord)
+
+-- | A list of pairs of separator and value. Separated by @a@ in values @b@.
+-- There is one more value than there are separators.
+data Separated1 b a =
+  Separated1 b (Separated a b)
+  deriving (Eq, Ord)
+
+-- | The @Separated@ type constructor, flipped.
+newtype Pesarated b a =
+  Pesarated (Separated a b)
+  deriving (Eq, Ord)
+
+-- | The @Separated1@ type constructor, flipped.
+newtype Pesarated1 a b =
+  Pesarated1 (Separated1 b a)
+  deriving (Eq, Ord)
+
+-- | The isomorphism to a list of pairs of element and separator values.
+--
+-- >>> separated # emptySeparated
+-- []
+--
+-- >>> separated # ('x' +: 6 +: emptySeparated)
+-- [('x',6)]
+--
+-- >>> [] ^. separated
+-- []
+--
+-- >>> [(6, [])] ^. separated
+-- [6,[]]
+separated ::
+  Iso [(a, b)] [(c, d)] (Separated a b) (Separated c d)
+separated =
+  from _Wrapped
+
+-- | The isomorphism to element values interspersed with a separator.
+--
+-- >>> separated1 # (singleSeparated 6)
+-- (6,[])
+--
+-- >>> separated1 # (5 +: 'x' +: singleSeparated 6)
+-- (5,['x',6])
+--
+-- >>> (6, emptySeparated) ^. separated1
+-- [6]
+--
+-- >>> (5, 'x' +- 6) ^. separated1
+-- [5,'x',6]
+separated1 ::
+  Iso (a, Separated s a) (b, Separated t b) (Separated1 a s) (Separated1 b t)
+separated1 =
+  iso (uncurry Separated1) (\(Separated1 a x) -> (a, x))
+
+-- | The isomorphism to element values interspersed with a separator.
+--
+-- >>> pesarated # emptyPesarated
+-- []
+--
+-- >>> ('a', 'x' +- 6) ^. pesarated1
+-- ['a',6,'x']
+--
+-- >>> ('x' -: 6 -: emptyPesarated)
+-- ['x',6]
+pesarated ::
+  Iso [(a, b)] [(c, d)] (Pesarated b a) (Pesarated d c)
+pesarated =
+  separated . from _Wrapped
+
+-- | The isomorphism to element values interspersed with a separator.
+--
+-- >>> pesarated1 # singlePesarated 6
+-- (6,[])
+--
+-- >>> pesarated1 # (8 -: 'x' -: singlePesarated 6)
+-- (8,['x',6])
+--
+-- >>> (6, empty) ^. pesarated1
+-- [6]
+--
+-- >>> (5, 'x' -+ 6) ^. pesarated1
+-- [5,'x',6]
+pesarated1 ::
+  Iso (a, Pesarated a s) (b, Pesarated b t) (Pesarated1 s a) (Pesarated1 t b)
+pesarated1 =
+  iso
+    (\(a, Pesarated x) -> Pesarated1 (Separated1 a x))
+    (\(Pesarated1 (Separated1 a x)) -> (a, Pesarated x))
+
+-- | Structures that have a head element.
+class HasHead s t a b | s -> a, t -> b, s b -> t, t a -> s where
+  headL ::
+    Lens s t a b
+
+-- | A lens on the first element value.
+--
+-- >>> (singleSeparated 7 :: Separated1 Int Char) ^. headL
+-- 7
+--
+-- prop> (singleSeparated x :: Separated1 Int Char) ^. headL == (x :: Int)
+instance HasHead (Separated1 a t) (Separated1 a t) a a where
+  headL =
+    from separated1 . _1
+
+-- | A lens on the first element value.
+--
+-- >>> (singlePesarated 7 :: Pesarated1 Char Int) ^. headL
+-- 7
+--
+-- prop> (singlePesarated x :: Pesarated1 Char Int) ^. headL == (x :: Int)
+instance HasHead (Pesarated1 a t) (Pesarated1 a t) t t where
+  headL =
+    _Wrapped . headL
+
+-- | Structures that have a tail.
+class HasTail s t a b | s -> a, t -> b, s b -> t, t a -> s where
+  tailL ::
+    Lens s t a b
+
+-- | A lens on the tail.
+--
+-- prop> (d +: e +: (singleSeparated x :: Separated1 Int Char)) ^. tailL == e +: x +: emptySeparated
+instance HasTail (Separated1 a s) (Separated1 a t) (Separated s a) (Separated t a) where
+  tailL =
+    from separated1 . _2
+
+-- | A lens on the tail.
+--
+-- prop> (d -: e -: (singlePesarated x :: Pesarated1 Char Int)) ^. tailL == e -: x -: emptyPesarated
+instance HasTail (Pesarated1 a s) (Pesarated1 b s) (Pesarated s a) (Pesarated s b) where
+  tailL =
+    _Wrapped . tailL . from _Wrapped
+
+-- | Construct a single separated value.
+class Separated1Single f where
+  singleSeparated ::
+    a
+    -> f a s
+
+-- | Zero element values interspersed with one element.
+--
+-- >>> (singleSeparated 4 :: Separated1 Int Char)
+-- [4]
+--
+-- prop> (singleSeparated x  :: Separated1 Int Char) ^. tailL == emptySeparated
+instance Separated1Single Separated1 where
+  singleSeparated a =
+    Separated1 a mempty
+
+class Pesarated1Single f where
+  singlePesarated ::
+    a
+    -> f s a
+
+-- | Zero element values interspersed with one element.
+--
+-- >>>  (singlePesarated 4 :: Pesarated1 Char Int)
+-- [4]
+--
+-- prop> (singlePesarated x  :: Pesarated1 Int Char) ^. tailL == emptyPesarated
+instance Pesarated1Single Pesarated1 where
+  singlePesarated a =
+    Pesarated1 (Separated1 a mempty)
+
+-- | Construction of separated values.
+class Construct f where
+  (+-) ::
+    s
+    -> a
+    -> f s a
+  (-+) ::
+    s
+    -> a
+    -> f a s
+  empty ::
+    f s a
+  sprinkle ::
+    s
+    -> [a]
+    -> f s a
+
+infixl 9 +-
+
+-- | One element and one separator.
+--
+-- >>> (7 +- "abc") :: Separated Int String
+-- [7,"abc"]
+--
+-- >>> 7 +: "abc" +: (8 +- "def") :: Separated Int String 
+-- [7,"abc",8,"def"]
+instance Construct Separated where
+  s +- a =
+    Separated [(s, a)]
+  s -+ a =
+    swapped # (s +- a)
+  empty =
+    Separated mempty
+  sprinkle s as =
+    Separated
+      ((,) s <$> as)
+
+-- | One element and one separator.
+--
+-- >>> (7 -+ "abc") :: Pesarated String Int
+-- [7,"abc"]
+--
+-- >>> 7 -: "abc" -: (8 -+ "def") :: Pesarated String Int
+-- [7,"abc",8,"def"]
+instance Construct Pesarated where
+  s +- a =
+    swapped . _Wrapped # (s +- a)
+  s -+ a =
+    _Wrapped # (s +- a)
+  empty =
+    Pesarated empty
+  sprinkle s as =
+    Pesarated
+      (swapped # sprinkle s as)
+
+-- | Prepend a value to a separated-like structure.
+class (f ~ SeparatedConsF g, g ~ SeparatedConsG f) => SeparatedCons f g where
+  type SeparatedConsF g :: * -> * -> *
+  type SeparatedConsG f :: * -> * -> *
+  (+:) ::
+    a
+    -> f b a
+    -> g a b
+  
+infixr 5 +:
+
+instance SeparatedCons Separated1 Separated where
+  type SeparatedConsF Separated = Separated1
+  type SeparatedConsG Separated1 = Separated
+  s +: Separated1 a (Separated x) =
+    Separated ((s, a) : x)
+
+instance SeparatedCons Separated Separated1 where
+  type SeparatedConsF Separated1 = Separated
+  type SeparatedConsG Separated = Separated1
+  (+:) =
+    Separated1
+
+-- | Prepend a value to a separated-like structure.
+class (f ~ PesaratedConsF g, g ~ PesaratedConsG f) => PesaratedCons f g where
+  type PesaratedConsF g :: * -> * -> *
+  type PesaratedConsG f :: * -> * -> *
+  (-:) ::
+    b
+    -> f b a
+    -> g a b
+  
+infixr 5 -:
+
+instance PesaratedCons Pesarated Pesarated1 where
+  type PesaratedConsF Pesarated1 = Pesarated
+  type PesaratedConsG Pesarated = Pesarated1
+  b -: (Pesarated x) =
+    Pesarated1
+      (b +: x)
+
+instance PesaratedCons Pesarated1 Pesarated where
+  type PesaratedConsF Pesarated = Pesarated1
+  type PesaratedConsG Pesarated1 = Pesarated
+  b -: (Pesarated1 x) =
+    Pesarated (b +: x)
+
+-- | Append two to make one.
+class Appends a b c | a b -> c where
+  (<++>) ::
+    a
+    -> b
+    -> c
+
+infixr 5 <++>
+
+-- | Append two lists of separated values to produce a list of pairs of separator and element values.
+--
+-- >>> (singleSeparated 7 :: Separated1 Int Char) <++> (singleSeparated 'a' :: Separated1 Char Int)
+-- [7,'a']
+--
+-- 'a' +: (singleSeparated 7 :: Separated1 Int Char) <++> (singleSeparated 'b' :: Separated1 Char Int)
+-- ['a',7,'b']
+--
+-- prop> a +: (b :: Separated Int Int) == a +: b --  (a +: (b <++> c)) == ((a +: b) <++> c)
+instance Appends (Separated1 s a) (Separated1 a s) (Separated s a) where
+  Separated1 s x <++> Separated1 t (Separated y) =
+    let (q, r') = (s, x) ^. separated1 . shift
+    in Separated (q <> ((r', t) : y))
+
+-- | Append element values interspersed with a separator to a list of pairs of separator and element values.
+--
+-- >>> (emptySeparated :: Separated Int Char) <++> (singleSeparated 7 :: Separated1 Int Char)
+-- [7]
+--
+-- >>> (emptySeparated :: Separated Int Char) <++> 6 +: 'x' +: (singleSeparated 7 :: Separated1 Int Char)
+-- [6,'x',7]
+--
+-- >>> 'w' +: (emptySeparated :: Separated Int Char) <++> 6 +: 'x' +: (singleSeparated 7 :: Separated1 Int Char)
+-- ['w',6,'x',7]
+instance Appends (Separated s a) (Separated1 s a) (Separated1 s a) where
+  Separated x <++> Separated1 t y =
+    let (z, w') = separated1 . shift # (x, t)
+    in Separated1 z (w' <> y)
+
+-- | Append a list of pairs of separator and element values to element values interspersed with a separator.
+--
+-- >>> (singleSeparated 7 :: Separated1 Int Char) <++> (emptySeparated :: Separated Char Int)
+-- [7]
+--
+-- >>> (singleSeparated 6 :: Separated1 Int Char) <++> 'x' +: 7 +: (emptySeparated :: Separated Char Int)
+-- [6,'x',7]
+--
+-- >>> 'w' +: (singleSeparated 6 :: Separated1 Int Char) <++> 'x' +: 7 +: (emptySeparated :: Separated Char Int)
+-- ['w',6,'x',7]
+instance Appends (Separated1 a s) (Separated s a) (Separated1 a s) where
+  Separated1 a x <++> y =
+    Separated1 a (x <> y)
+
+-- | Alternate separated values e.g. `f ~ Parser`.
+--
+-- >>> parse (separatedBy (char ',') digit) "test" ""
+-- Right []
+--
+-- >>> isLeft (parse (separatedBy (char ',') digit) "test" ",")
+-- True
+--
+-- >>> parse (separatedBy (char ',') digit) "test" ",1"
+-- Right [',','1']
+--
+-- >>> isLeft (parse (separatedBy (char ',') digit) "test" ",1,")
+-- True
+--
+-- >>> parse (separatedBy (char ',') digit) "test" ",1,2,3,4,5"
+-- Right [',','1',',','2',',','3',',','4',',','5']
+separatedBy ::
+  Alternative f =>
+  f a
+  -> f b
+  -> f (Separated a b)
+separatedBy a b =
+  Separated <$>
+    many
+      ((,) <$> a <*> b)
+
+-- | Alternate separated values e.g. `f ~ Parser`.
+--
+-- >>> isLeft (parse (separatedBy1 (char ',') digit) "test" "")
+-- True
+--
+-- >>> parse (separatedBy1 (char ',') digit) "test" ","
+-- Right [',']
+--
+-- >>> isLeft (parse (separatedBy1 (char ',') digit) "test" ",1")
+-- True
+--
+-- >>> parse (separatedBy1 (char ',') digit) "test" ",1,"
+-- Right [',','1',',']
+--
+-- >>>  parse (separatedBy1 (char ',') digit) "test" ",1,2,3,4,5,"
+-- Right [',','1',',','2',',','3',',','4',',','5',',']
+separatedBy1 ::
+  Alternative f =>
+  f b
+  -> f a
+  -> f (Separated1 b a)
+separatedBy1 b a =
+  Separated1 <$> b <*> separatedBy a b
+
+-- | Alternate separated values e.g. `f ~ Parser`.
+--
+-- >>> parse (pesaratedBy (char ',') digit) "test" ""
+-- Right []
+--
+-- >>> isLeft (parse (pesaratedBy (char ',') digit) "test" ",")
+-- True
+--
+-- >>> parse (separatedBy (char ',') digit) "test" ",1"
+-- Right [',','1']
+--
+-- >>> isLeft (parse (pesaratedBy (char ',') digit) "test" ",1,")
+-- True
+--
+-- >>> parse (pesaratedBy (char ',') digit) "test" ",1,2,3,4,5"
+-- Right [',','1',',','2',',','3',',','4',',','5']
+pesaratedBy ::
+  Alternative f =>
+  f a
+  -> f b
+  -> f (Pesarated b a)
+pesaratedBy a b =
+  Pesarated <$> separatedBy a b
+
+-- | Alternate separated values e.g. `f ~ Parser`.
+--
+-- >>> isLeft (parse (pesaratedBy1 (char ',') digit) "test" "")
+-- True
+--
+-- >>> parse (pesaratedBy1 (char ',') digit) "test" ","
+-- Right [',']
+--
+-- >>> isLeft (parse (pesaratedBy1 (char ',') digit) "test" ",1")
+-- True
+--
+-- >>> parse (pesaratedBy1 (char ',') digit) "test" ",1,"
+-- Right [',','1',',']
+--
+-- >>>  parse (pesaratedBy1 (char ',') digit) "test" ",1,2,3,4,5,"
+-- Right [',','1',',','2',',','3',',','4',',','5',',']
+pesaratedBy1 ::
+  Alternative f =>
+  f b
+  -> f a
+  -> f (Pesarated1 a b)
+pesaratedBy1 b a =
+  Pesarated1 <$> separatedBy1 b a
+
+-- | The isomorphism that swaps elements with their separators.
+--
+-- >>> swapped # emptySeparated
+-- []
+--
+-- >>> swapped # ('x' +: 6 +: emptySeparated)
+-- [6,'x']
+--
+-- >>> emptySeparated ^. swapped
+-- []
+--
+-- >>> ('x' +: 6 +: emptySeparated) ^. swapped
+-- [6,'x']
+instance Swapped Separated where
+  swapped =
+    let swap = (\(Separated x) -> Separated (fmap (\(a, b) -> (b, a)) x))
+    in iso swap swap
+
+instance Bifunctor Separated where
+  bimap f g (Separated x) =
+    Separated (fmap (bimap f g) x)
+
+instance Bifoldable Separated where
+  bifoldr f g z (Separated x) =
+    foldr (\(a, b) -> f a . g b) z x
+
+instance Bitraversable Separated where
+  bitraverse f g (Separated x) =
+    Separated <$> traverse (\(a, b) -> (,) <$> f a <*> g b) x
+
+-- | Map across a @Separated@ on the element values.
+--
+-- prop> fmap id (x :: Separated Int String) == x
+--
+-- prop> \a b -> fmap (+1) (a +: b +: emptySeparated) == a +: (1+b) +: emptySeparated
+instance Functor (Separated a) where
+  fmap =
+    bimap id
+
+-- | Applies functions with element values, using a zipping operation, appending
+-- separators.
+--
+-- >>> (emptySeparated :: Separated [Int] (String -> [String])) <.> emptySeparated
+-- []
+--
+-- >>> [1,2] +: (\s -> [s, reverse s, drop 1 s]) +: emptySeparated <.> [3,4,5] +: "abc" +: emptySeparated
+-- [[1,2,3,4,5],["abc","cba","bc"]]
+instance Semigroup a => Apply (Separated a) where
+  (<.>) =
+    separatedAp (<>)
+
+-- | Applies functions with element values, using a zipping operation, appending
+-- separators. The identity operation is an infinite list of the emptySeparated separator
+-- and the given element value.
+--
+-- >>> (emptySeparated :: Separated [Int] (String -> [String])) <*> emptySeparated
+-- []
+--
+-- >>> [1,2] +: (\s -> [s, reverse s, drop 1 s]) +: emptySeparated <*> [3,4,5] +: "abc" +: emptySeparated
+-- [[1,2,3,4,5],["abc","cba","bc"]]
+instance Monoid a => Applicative (Separated a) where    
+  (<*>) =
+    separatedAp mappend
+  pure =
+    Separated . repeat . (,) mempty
+
+-- |
+--
+-- >>> show (emptySeparated :: Separated () ())
+-- "[]"
+--
+-- >>> show ('x' +: (6 :: Int) +: emptySeparated)
+-- "['x',6]"
+instance (Show a, Show b) => Show (Separated a b) where
+  show (Separated x) =
+    showSeparated id x
+
+-- |
+--
+-- >>> ('x' +: (6 :: Int) +: emptySeparated) <> ('y' +: 7 +: emptySeparated)
+-- ['x',6,'y',7]
+instance Semigroup (Separated a b) where
+  Separated x <> Separated y =
+    Separated (x <> y)    
+
+-- |
+--
+-- >>> ('x' +: (6 :: Int) +: emptySeparated) `mappend` ('y' +: 7 +: emptySeparated)
+-- ['x',6,'y',7]
+instance Monoid (Separated a b) where
+  mappend =
+    (<>)
+  mempty =
+    Separated mempty
+
+----
+
+instance Bifunctor Separated1 where
+  bimap f g (Separated1 a x) =
+    Separated1 (f a) (bimap g f x)
+
+instance Bifoldable Separated1 where
+  bifoldr f g z (Separated1 a x) = 
+    f a (bifoldr g f z x)
+
+instance Bitraversable Separated1 where
+  bitraverse f g (Separated1 a x) =
+    Separated1 <$> f a <*> bitraverse g f x
+
+-- | Map across a @Separated1@ on the separator values.
+--
+-- >>> fmap (+1) (set tailL (1 +: 'b' +: 2 +: 'c' +: emptySeparated) (singleSeparated 'a' :: Separated1 Char Int))
+-- ['a',2,'b',3,'c']
+--
+-- prop> fmap id (x :: Separated1 Int String) == x
+--
+-- prop> fmap (+1) (singleSeparated x :: Separated1 Char Int) == singleSeparated x
+instance Functor (Separated1 b) where
+  fmap =
+    bimap id
+
+-- | Applies functions with separator values, using a zipping operation,
+-- appending elements.
+--
+-- >>> [1,2] +: reverse +: [3,4] +: emptySeparated <.> [5,6,7] +: "abc" +: [8] +: emptySeparated
+-- [[1,2,5,6,7],"cba",[3,4,8]]
+instance Semigroup b => Apply (Separated1 b) where
+  (<.>) =
+    separated1Ap (<>)
+
+-- | Applies functions with separator values, using a zipping operation,
+-- appending elements. The identity operation is an infinite list of the emptySeparated
+-- element and the given separator value.
+--
+-- >>> [1,2] +: reverse +: [3,4] +: emptySeparated <*> [5,6,7] +: "abc" +: [8] +: emptySeparated
+-- [[1,2,5,6,7],"cba",[3,4,8]]
+instance Monoid b => Applicative (Separated1 b) where    
+  (<*>) =
+    separated1Ap mappend
+  pure =
+    Separated1 mempty . (swapped #) . pure
+
+instance (Show b, Show a) => Show (Separated1 b a) where
+  show (Separated1 a (Separated x)) =
+    showSeparated (show a:) x
+
+-- | The isomorphism that swaps elements with their separators.
+--
+-- >>> swapped # emptyPesarated
+-- []
+--
+-- >>> swapped # ('x' -: 6 -: emptyPesarated)
+-- [6,'x']
+--
+-- >>> emptyPesarated ^. swapped
+-- []
+--
+-- >>> ('x' -: 6 -: emptyPesarated) ^. swapped
+-- [6,'x']
+instance Swapped Pesarated where
+  swapped =
+    _Wrapped . swapped . from _Wrapped
+
+instance Bifunctor Pesarated where
+  bimap f g (Pesarated x) =
+    Pesarated (bimap g f x)
+
+instance Bifoldable Pesarated where
+  bifoldr f g z (Pesarated x) =
+    bifoldr g f z x
+
+instance Bitraversable Pesarated where
+  bitraverse f g (Pesarated x) =
+    Pesarated <$> bitraverse g f x
+
+-- | Map across a @Pesarated@ on the element values.
+--
+-- prop> fmap id (x :: Pesarated Int String) == x
+--
+-- prop> \a b -> fmap (+1) (a -: b -: emptyPesarated) == (1+a) -: b -: emptyPesarated
+instance Functor (Pesarated a) where
+  fmap f (Pesarated x) =
+    Pesarated (first f x)
+
+-- | Applies functions with element values, using a zipping operation, appending
+-- separators.
+--
+-- >>> (emptyPesarated :: Pesarated [Int] (String -> [String])) <.> emptyPesarated
+-- []
+--
+-- >>> (\s -> [s, reverse s, drop 1 s]) -: [1,2] -: emptyPesarated <.> "abc" -: [3,4,5] -: emptyPesarated
+-- [["abc","cba","bc"],[1,2,3,4,5]]
+instance Semigroup a => Apply (Pesarated a) where
+  Pesarated f <.> Pesarated a =
+    Pesarated ((swapped # f <.> swapped # a) ^. swapped)
+
+-- | Applies functions with element values, using a zipping operation, appending
+-- separators. The identity operation is an infinite list of the emptySeparated separator
+-- and the given element value.
+--
+-- >>> (emptySeparated :: Separated [Int] (String -> [String])) <*> emptySeparated
+-- []
+--
+-- >>> (\s -> [s, reverse s, drop 1 s]) -: [1,2] -: emptyPesarated <*> "abc" -: [3,4,5] -: emptyPesarated
+-- [["abc","cba","bc"],[1,2,3,4,5]]
+instance Monoid a => Applicative (Pesarated a) where
+  Pesarated f <*> Pesarated a =
+    Pesarated ((swapped # f <*> swapped # a) ^. swapped)
+  pure a =
+    Pesarated (pure a ^. swapped)
+
+-- |
+--
+-- >>> show (emptyPesarated :: Pesarated () ())
+-- "[]"
+--
+-- >>> show ('x' -: (6 :: Int) -: emptyPesarated)
+-- "['x',6]"
+instance (Show a, Show b) => Show (Pesarated b a) where
+  show (Pesarated x) =
+    show x
+
+-- |
+--
+-- >>> ('x' -: (6 :: Int) -: emptyPesarated) <> ('y' -: 7 -: emptyPesarated)
+-- ['x',6,'y',7]
+instance Semigroup (Pesarated b a) where
+  Pesarated a <> Pesarated b =
+    Pesarated (a <> b)
+
+-- |
+--
+-- >>> ('x' -: (6 :: Int) -: emptyPesarated) `mappend` ('y' -: 7 -: emptyPesarated)
+-- ['x',6,'y',7]
+instance Monoid (Pesarated b a) where
+  Pesarated a `mappend` Pesarated b =
+    Pesarated (a <> b)
+  mempty =
+    Pesarated mempty
+
+instance Bifunctor Pesarated1 where
+  bimap f g (Pesarated1 x) =
+    Pesarated1 (bimap g f x)
+
+instance Bifoldable Pesarated1 where
+  bifoldr f g z (Pesarated1 x) =
+    bifoldr g f z x
+
+instance Bitraversable Pesarated1 where
+  bitraverse f g (Pesarated1 x) =
+    Pesarated1 <$> bitraverse g f x
+
+-- | Map across a @Pesarated1@ on the separator values.
+--
+-- >>> fmap toUpper (set tailL (1 -: 'b' -: 2 -: 'c' -: empty) (singlePesarated 'z' :: Pesarated1 Int Char) :: Pesarated1 Int Char)
+-- ['Z',1,'B',2,'C']
+--
+-- prop> fmap id (x :: Pesarated1 Int String) == x
+--
+-- prop> fmap (+1) (singlePesarated x :: Pesarated1 Char Int) == singlePesarated (x + 1)
+instance Functor (Pesarated1 a) where
+  fmap f (Pesarated1 x) =
+    Pesarated1 (first f x)
+
+-- | Applies functions with separator values, using a zipping operation,
+-- appending elements.
+--
+-- >>> id -: [1,2] -: reverse -: [3,4] -: emptyPesarated <.> "def" -: [5,6,7] -: "abc" -: [8] -: emptyPesarated
+-- ["def",[1,2,5,6,7],"cba",[3,4,8]]
+instance Semigroup a => Apply (Pesarated1 a) where
+  f <.> a =
+    pesarated1Ap (<>) f a
+
+-- | Applies functions with separator values, using a zipping operation,
+-- appending elements. The identity operation is an infinite list of the emptySeparated
+-- element and the given separator value.
+--
+-- >>> id -: [1,2] -: reverse -: [3,4] -: emptyPesarated <*> "def" -: [5,6,7] -: "abc" -: [8] -: emptyPesarated
+-- ["def",[1,2,5,6,7],"cba",[3,4,8]]
+instance Monoid a => Applicative (Pesarated1 a) where
+  f <*> a =
+    pesarated1Ap mappend f a
+  pure a =
+    Pesarated1 (Separated1 a (pure a))
+
+instance (Show a, Show b) => Show (Pesarated1 a b) where
+  show (Pesarated1 x) =
+    show x
+
+---- not exported
+
+showSeparated ::
+ (Show a, Show s, Functor f) =>
+ (f String -> [String])
+ -> f (s, a)
+ -> String
+showSeparated f x =
+  '[' : intercalate "," (f (fmap (\(s, a) -> show s <> "," <> show a) x)) <> "]"
+
+separatedAp ::
+  (s -> s -> s)
+  -> Separated s (a -> b)
+  -> Separated s a
+  -> Separated s b
+separatedAp opp (Separated f) (Separated a) =
+    Separated (zipWith (\(s, f') (t, a') -> (s `opp` t, f' a')) f a)  
+
+separated1Ap ::
+  (a -> a -> a)
+  -> Separated1 a (s -> t)
+  -> Separated1 a s
+  -> Separated1 a t
+separated1Ap opp (Separated1 f (Separated fs)) (Separated1 a (Separated as)) =
+    Separated1 (f `opp` a) (Separated (zipWith (\(s, f') (t, a') -> (s t, f' `opp` a')) fs as))
+
+pesarated1Ap ::
+  (a -> a -> a)
+  -> Pesarated1 a (s -> t)
+  -> Pesarated1 a s
+  -> Pesarated1 a t
+pesarated1Ap opp (Pesarated1 (Separated1 f (Separated fs))) (Pesarated1 (Separated1 a (Separated as))) =
+  Pesarated1 (Separated1 (f a) (Separated (zipWith (\(s, f') (t, a') -> (s `opp` t, f' a')) fs as)))
+
+-- | The isomorphism that shuffles the elements and separators one position.
+--
+-- >>> shift # ([], 6)
+-- [6]
+--
+-- >>> shift # ([(5, 'x')], 6)
+-- [5,'x',6]
+--
+-- >>> singleSeparated 6 ^. shift
+-- ([],6)
+--
+-- >>> (5 +: 'x' +: singleSeparated 6) ^. shift
+-- ([(5,'x')],6)
+shift ::
+  Iso (Separated1 a s) (Separated1 b t) ([(a, s)], a) ([(b, t)], b)
+shift =
+  let shiftR ([], a) =
+        Separated1 a (Separated [])
+      shiftR ((b, s):r, a) =
+        let Separated1 z' (Separated w) = shiftR (r, b)
+        in Separated1 z' (Separated ((s, a) : w))
+      shiftL (Separated1 s' (Separated [])) =
+        ([], s')
+      shiftL (Separated1 s' (Separated ((a, t') : r))) =
+        let (w, z) = shiftL (Separated1 t' (Separated r))
+        in ((s', a) : w, z)
+  in iso shiftL shiftR
+
+makeWrapped ''Separated
+makeWrapped ''Pesarated
+makeWrapped ''Pesarated1
diff --git a/src/Data/Separated/Separated.hs b/src/Data/Separated/Separated.hs
deleted file mode 100644
--- a/src/Data/Separated/Separated.hs
+++ /dev/null
@@ -1,443 +0,0 @@
-{-# LANGUAGE NoImplicitPrelude #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE FlexibleInstances #-}
-
-module Data.Separated.Separated(
-  Separated
-, separated
-, Separated1
-, separated1
--- * Viewing
-, separated1Head
-, separated1Tail
--- Constructing
-, empty
-, (+-)
-, single
--- * Appending
-, shift
-, (.++.)
-, (++.)
-, (.++)
--- * Alternating
-, separatedBy
-, separatedBy1
-) where
-
-import Control.Applicative(Alternative(many))
-import Data.Bifoldable(Bifoldable(bifoldr))
-import Data.Bitraversable(Bitraversable(bitraverse))
-import Data.Functor.Apply as Apply((<.>))
-import Data.List(intercalate, zipWith, repeat)
-import Data.Monoid as Monoid(mappend)
-import Data.Semigroup as Semigroup((<>))
-import Data.Separated.SeparatedCons(SeparatedCons((+:), SeparatedConsF, SeparatedConsG))
-import Data.String(String)
-import Papa hiding ((<.>))
-
--- $setup
--- >>> :set -XNoImplicitPrelude
--- >>> import Data.Char(toUpper)
--- >>> import Data.Either(isLeft)
--- >>> import Text.Parsec(parse, char, digit)
--- >>> import Test.QuickCheck(Arbitrary(..))
--- >>> instance (Arbitrary s, Arbitrary a) => Arbitrary (Separated s a) where arbitrary = fmap (^. separated) arbitrary
--- >>> instance (Arbitrary a, Arbitrary s) => Arbitrary (Separated1 s a) where arbitrary = do a <- arbitrary; x <- arbitrary; return ((a, x) ^. separated1)
-
-
-newtype Separated a b =
-  Separated [(a, b)]
-  deriving (Eq, Ord)
-
-makeWrapped ''Separated
-
--- | The isomorphism that swaps elements with their separators.
---
--- >>> swapped # empty
--- []
---
--- >>> swapped # ('x' +: 6 +: empty)
--- [6,'x']
---
--- >>> empty ^. swapped
--- []
---
--- >>> ('x' +: 6 +: empty) ^. swapped
--- [6,'x']
-instance Swapped Separated where
-  swapped =
-    let swap = (\(Separated x) -> Separated (fmap (\(a, b) -> (b, a)) x))
-    in iso swap swap
-
-instance Bifunctor Separated where
-  bimap f g (Separated x) =
-    Separated (fmap (bimap f g) x)
-
-instance Bifoldable Separated where
-  bifoldr f g z (Separated x) =
-    foldr (\(a, b) -> f a . g b) z x
-
-instance Bitraversable Separated where
-  bitraverse f g (Separated x) =
-    Separated <$> traverse (\(a, b) -> (,) <$> f a <*> g b) x
-
--- | Map across a @Separated@ on the element values.
---
--- prop> fmap id (x :: Separated Int String) == x
---
--- prop> \a b -> fmap (+1) (a +: b +: empty) == a +: (1+b) +: empty
-instance Functor (Separated a) where
-  fmap =
-    bimap id
-
--- | Applies functions with element values, using a zipping operation, appending
--- separators.
---
--- >>> (empty :: Separated [Int] (String -> [String])) <.> empty
--- []
---
--- >>> [1,2] +: (\s -> [s, reverse s, drop 1 s]) +: empty <.> [3,4,5] +: "abc" +: empty
--- [[1,2,3,4,5],["abc","cba","bc"]]
-instance Semigroup a => Apply (Separated a) where
-  (<.>) =
-    separatedAp (<>)
-
--- | Applies functions with element values, using a zipping operation, appending
--- separators. The identity operation is an infinite list of the empty separator
--- and the given element value.
---
--- >>> (empty :: Separated [Int] (String -> [String])) <*> empty
--- []
---
--- >>> [1,2] +: (\s -> [s, reverse s, drop 1 s]) +: empty <*> [3,4,5] +: "abc" +: empty
--- [[1,2,3,4,5],["abc","cba","bc"]]
-instance (Semigroup a, Monoid a) => Applicative (Separated a) where    
-  (<*>) =
-    separatedAp (<>)
-  pure =
-    Separated . repeat . (,) mempty
-
-instance (Show a, Show b) => Show (Separated a b) where
-  show (Separated x) =
-    showSeparated id x
-
-instance Semigroup (Separated a b) where
-  Separated x <> Separated y =
-    Separated (x <> y)    
-
-instance Monoid (Separated a b) where
-  mappend =
-    (<>)
-  mempty =
-    Separated mempty
-
-instance SeparatedCons Separated1 Separated where
-  type SeparatedConsF Separated = Separated1
-  type SeparatedConsG Separated1 = Separated
-  s +: Separated1 a (Separated x) =
-    Separated ((s, a) : x)
-
-----
-
-data Separated1 b a =
-  Separated1 b (Separated a b)
-  deriving (Eq, Ord)
-
-instance Bifunctor Separated1 where
-  bimap f g (Separated1 a x) =
-    Separated1 (f a) (bimap g f x)
-
--- | Map across a @Separated1@ on the separator values.
---
--- >>> fmap (+1) (set separated1Tail (1 +: 'b' +: 2 +: 'c' +: empty) (single 'a'))
--- ['a',2,'b',3,'c']
---
--- prop> fmap id (x :: Separated1 Int String) == x
---
--- prop> fmap (+1) (single x) == single x
-instance Functor (Separated1 b) where
-  fmap =
-    bimap id
-
--- | Applies functions with separator values, using a zipping operation,
--- appending elements.
---
--- >>> [1,2] +: reverse +: [3,4] +: empty <.> [5,6,7] +: "abc" +: [8] +: empty
--- [[1,2,5,6,7],"cba",[3,4,8]]
-instance Semigroup b => Apply (Separated1 b) where
-  (<.>) =
-    separated1Ap (<>)
-
-instance (Show b, Show a) => Show (Separated1 b a) where
-  show (Separated1 a (Separated x)) =
-    showSeparated (show a:) x
-    
--- | Applies functions with separator values, using a zipping operation,
--- appending elements. The identity operation is an infinite list of the empty
--- element and the given separator value.
---
--- >>> [1,2] +: reverse +: [3,4] +: empty <*> [5,6,7] +: "abc" +: [8] +: empty
--- [[1,2,5,6,7],"cba",[3,4,8]]
-instance (Semigroup b, Monoid b) => Applicative (Separated1 b) where    
-  (<*>) =
-    separated1Ap (<>)
-  pure =
-    Separated1 mempty . (swapped #) . pure
-
-instance SeparatedCons Separated Separated1 where
-  type SeparatedConsF Separated1 = Separated
-  type SeparatedConsG Separated = Separated1
-  (+:) =
-    Separated1
-
-----
-
--- | The isomorphism to a list of pairs of element and separator values.
---
--- >>> separated # empty
--- []
---
--- >>> separated # ('x' +: 6 +: empty)
--- [('x',6)]
---
--- >>> [] ^. separated
--- []
---
--- >>> [(6, [])] ^. separated
--- [6,[]]
-separated ::
-  Iso [(a, b)] [(c, d)] (Separated a b) (Separated c d)
-separated =
-  from _Wrapped
-
-empty ::
-  Separated s a
-empty =
-  Separated []
-
--- | The isomorphism to element values interspersed with a separator.
---
--- >>> separated1 # (single 6)
--- (6,[])
---
--- >>> separated1 # (5 +: 'x' +: single 6)
--- (5,['x',6])
---
--- >>> (6, empty) ^. separated1
--- [6]
---
--- >>> (5, 'x' +- 6) ^. separated1
--- [5,'x',6]
-separated1 ::
-  Iso (a, Separated s a) (b, Separated t b) (Separated1 a s) (Separated1 b t)
-separated1 =
-  iso (uncurry Separated1) (\(Separated1 a x) -> (a, x))
-
--- | A lens on the first element value.
---
--- >>> single 7 ^. separated1Head
--- 7
---
--- prop> single x ^. separated1Head == (x :: Int)
-separated1Head ::
-  Lens (Separated1 a t) (Separated1 a t) a a
-separated1Head =
-  from separated1 . _1
-
--- | A lens on the tail.
---
--- prop> (d +: e +: single x) ^. separated1Tail == e +: x +: empty
-separated1Tail ::
-  Lens (Separated1 a s) (Separated1 a t) (Separated s a) (Separated t a)
-separated1Tail =
-  from separated1 . _2
-
--- | One element and one separator.
---
--- >>> 7 +- "abc"
--- [7,"abc"]
---
--- >>> 7 +: "abc" +: 8 +- "def"
--- [7,"abc",8,"def"]
-(+-) ::
-  s
-  -> a
-  -> Separated s a
-s +- a =
-  s +: single a
-
-infixl 9 +-
-
--- | Zero element values interspersed with one element.
---
--- >>> single 4
--- [4]
---
--- prop> single x ^. separated1Tail == empty
-single ::
-  a
-  -> Separated1 a s
-single a =
-  Separated1 a empty
-
--- | The isomorphism that shuffles the elements and separators one position.
---
--- >>> shift # ([], 6)
--- [6]
---
--- >>> shift # ([(5, 'x')], 6)
--- [5,'x',6]
---
--- >>> single 6 ^. shift
--- ([],6)
---
--- >>> (5 +: 'x' +: single 6) ^. shift
--- ([(5,'x')],6)
-shift ::
-  Iso (Separated1 a s) (Separated1 b t) ([(a, s)], a) ([(b, t)], b)
-shift =
-  let shiftR ([], a) =
-        Separated1 a (Separated [])
-      shiftR ((b, s):r, a) =
-        let Separated1 z' (Separated w) = shiftR (r, b)
-        in Separated1 z' (Separated ((s, a) : w))
-      shiftL (Separated1 s' (Separated [])) =
-        ([], s')
-      shiftL (Separated1 s' (Separated ((a, t') : r))) =
-        let (w, z) = shiftL (Separated1 t' (Separated r))
-        in ((s', a) : w, z)
-  in iso shiftL shiftR
-
--- | Append two lists of separated values to produce a list of pairs of separator and element values.
---
--- >>> single 7 .++. single 'a'
--- [7,'a']
---
--- 'a' +: single 7 .++. single 'b'
--- ['a',7,'b']
---
--- prop> a +: (b :: Separated Int Int) == a +: b --  (a +: (b .++. c)) == ((a +: b) .++ c)
-(.++.) ::
-   Separated1 s a
-   -> Separated1 a s
-   -> Separated s a
-Separated1 s x .++. Separated1 t (Separated y) =
-  let (q, r') = (s, x) ^. separated1 . shift
-  in Separated (q <> ((r', t) : y)) 
-
-infixr 5 .++.
-
--- | Append element values interspersed with a separator to a list of pairs of separator and element values.
---
--- >>> empty ++. single 7
--- [7]
---
--- >>> empty ++. 6 +: 'x' +: single 7
--- [6,'x',7]
---
--- >>> 'w' +: empty ++. 6 +: 'x' +: single 7
--- ['w',6,'x',7]
-(++.) ::
-  Separated s a
-  -> Separated1 s a
-  -> Separated1 s a
-Separated x ++. Separated1 t y =
-  let (z, w') = separated1 . shift # (x, t)
-  in Separated1 z (w' <> y)
-
-infixr 5 ++.
-
--- | Append a list of pairs of separator and element values to element values interspersed with a separator.
---
--- >>> single 7 .++ empty
--- [7]
---
--- >>> single 6 .++ 'x' +: 7 +: empty
--- [6,'x',7]
---
--- >>> 'w' +: single 6 .++ 'x' +: 7 +: empty
--- ['w',6,'x',7]
-(.++) ::
-  Separated1 a s
-  -> Separated s a
-  -> Separated1 a s
-Separated1 a x .++ y =
-  Separated1 a (x <> y)
-
-infixr 5 .++
-
--- |
---
--- >>> parse (separatedBy (char ',') digit) "test" ""
--- Right []
---
--- >>> isLeft (parse (separatedBy (char ',') digit) "test" ",")
--- True
---
--- >>> parse (separatedBy (char ',') digit) "test" ",1"
--- Right [',','1']
---
--- >>> isLeft (parse (separatedBy (char ',') digit) "test" ",1,")
--- True
---
--- >>> parse (separatedBy (char ',') digit) "test" ",1,2,3,4,5"
--- Right [',','1',',','2',',','3',',','4',',','5']
-separatedBy ::
-  Alternative f =>
-  f a
-  -> f b
-  -> f (Separated a b)
-separatedBy a b =
-  Separated <$>
-    many
-      ((,) <$> a <*> b)
-
--- |
---
--- >>> isLeft (parse (separatedBy1 (char ',') digit) "test" "")
--- True
---
--- >>> parse (separatedBy1 (char ',') digit) "test" ","
--- Right [',']
---
--- >>> isLeft (parse (separatedBy1 (char ',') digit) "test" ",1")
--- True
---
--- >>> parse (separatedBy1 (char ',') digit) "test" ",1,"
--- Right [',','1',',']
---
--- >>>  parse (separatedBy1 (char ',') digit) "test" ",1,2,3,4,5,"
--- Right [',','1',',','2',',','3',',','4',',','5',',']
-separatedBy1 ::
-  Alternative f =>
-  f b
-  -> f a
-  -> f (Separated1 b a)
-separatedBy1 b a =
-  Separated1 <$> b <*> separatedBy a b
-
-showSeparated ::
- (Show a, Show s, Functor f) =>
- (f String -> [String])
- -> f (s, a)
- -> String
-showSeparated f x =
-  '[' : intercalate "," (f (fmap (\(s, a) -> show s <> "," <> show a) x)) <> "]"
-
-separatedAp ::
-  (s -> s -> s)
-  -> Separated s (a -> b)
-  -> Separated s a
-  -> Separated s b
-separatedAp opp (Separated f) (Separated a) =
-    Separated (zipWith (\(s, f') (t, a') -> (s `opp` t, f' a')) f a)  
-
-separated1Ap ::
-  (a -> a -> a)
-  -> Separated1 a (s -> t)
-  -> Separated1 a s
-  -> Separated1 a t
-separated1Ap opp (Separated1 f (Separated fs)) (Separated1 a (Separated as)) =
-    Separated1 (f `opp` a) (Separated (zipWith (\(s, f') (t, a') -> (s t, f' `opp` a')) fs as))
diff --git a/src/Data/Separated/SeparatedCons.hs b/src/Data/Separated/SeparatedCons.hs
deleted file mode 100644
--- a/src/Data/Separated/SeparatedCons.hs
+++ /dev/null
@@ -1,18 +0,0 @@
-{-# LANGUAGE NoImplicitPrelude #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-
-module Data.Separated.SeparatedCons(
-  SeparatedCons(..)
-) where
-
--- | Prepend a value to a separated-like structure.
-class (f ~ SeparatedConsF g, g ~ SeparatedConsG f) => SeparatedCons f g where
-  type SeparatedConsF g :: * -> * -> *
-  type SeparatedConsG f :: * -> * -> *
-  (+:) ::
-    a
-    -> f b a
-    -> g a b
-  
-infixr 5 +:
