diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,45 +1,38 @@
 # Changelog
 
-# 0.2
+## 0.2
 
 Highlights:
 
 * Switching from list-based parsing to `TokenStream`
 
-## 0.2.1
+### 0.2.2
 
-### 0.2.1.0
+* Added Either instance for `TokenStream`
+* Auto-`success` atomic, atomics for splitting an integer into digits
 
-* Deprecated `skipN`, replaced with `sDrop` 
+### 0.2.1
 
-## 0.2.0
+* Deprecated `skipN`, replaced with `sDrop` 
 
-### 0.2.0.0
+### 0.2.0
 
 * Added `TokenStream`, an abstraction of lists
 * Used `TokenStream` to reformulate Atomics and Transformers
 
-
-# 0.1
+## 0.1
 
 Highlights:
 
 * Initial Version
 
-## 0.1.4
-
-### 0.1.4.0
+### 0.1.4
 
 * Added `digit` and `letter` parsers
 
-## 0.1.3
-
-### 0.1.3.1
+### 0.1.3
 
 * Improved testing facilities
-
-### 0.1.3.0
-
 * Added `check` function
 
 ## 0.1.2
diff --git a/LParse.cabal b/LParse.cabal
--- a/LParse.cabal
+++ b/LParse.cabal
@@ -1,5 +1,5 @@
 name:                LParse
-version:             0.2.1.0
+version:             0.2.2.2
 synopsis:            A continuation-based parser library
 description:         A parser library using continuations with a possibility for failure to build parsers in a clear and concise manner.
 homepage:            https://github.com/MarcusVoelker/LParse#readme
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,4 +1,32 @@
-# λParse  ![Travis-CI](https://travis-ci.org/MarcusVoelker/LParse.svg?branch=master)
+# λParse  ![Travis-CI](https://travis-ci.org/MarcusVoelker/LParse.svg?branch=master) [![Hackage](https://img.shields.io/hackage/v/LParse.svg)](https://hackage.haskell.org/package/LParse)
 
-A parser library using monads and arrows. [Get it on hackage!](https://hackage.haskell.org/package/LParse)
+A parser library using monads and arrows. Supports both horizontal and vertical composition of parsers.
 
+# Short Guide
+
+## Creating a parser
+
+A parser is, at its heart, nothing more than a function that takes some input and either returns a result along with some residual, unconsumed input or that fails for some reason and returns an error message.
+
+Since LParse is written in continuation-passing-style, this is modelled with a concept of DoubleContinuations - continuations that not only take one function to continue with, but one function to continue with in the case of a successful computation and one function to continue with in the case of a failure. This, of course, gives rise to classic parser semantics: To concatenate two parsers, the second one is put into the successful continuation of the first one, while for an alternative we put the second parser into the failure continuation of the first one.
+
+These semantics are modelled with Monads and Alternatives, respectively, to make use of the familar syntax of these classes:
+
+* `p1 >> p2` runs `p1` and `p2` in succession and gives the result of `p2` only
+* `(,) <$> p1 <*> p2` runs `p1` and `p2` in succession and gives the results of `p1` and `p2` as a pair
+* `p1 <|> p2` runs `p1`. On a success, its result is returned, on a fail, `p2` is run. On a success, its result is returned, on a failure, the whole parser fails
+
+The parser can be built from scratch by constructing a parser object with the appropriate function, but a variety of common atomic parsers and parser transformers are provided in `Text.LParse.Atomics` and `Text.LParse.Transformers`, respectively.
+
+The above construction is referred to as _horizontal composition_, i.e., running parsers successively on the same input.
+The dual concept to this we refer to as _vertical composition_, where the result of one parser is fed into the next one as an input. An application for this could be one parser `lex` that transforms a string into a list of tokens (a lexer) and a second parser `par` that transforms a list of tokens into a syntax tree. Then we could join these to create a parser that directly transforms a string into a syntax tree as `lex >>> par`
+
+As the notation above implies, LParse realises vertical composition with arrows enabling all the other features of arrows, such as the proc notation, to be used with parsers.
+
+## Running a parser
+
+Once you have obtained a parser object that represents your entire parser, you have two options
+
+1. You can supply a success and a failure function. When the parser is run, the appropriate function will be called, either with the result of the parse or an error message
+
+2. You can retrieve the double continuation from the parser and continue to build with it. This is appropriate if your program itself is written in CPS.
diff --git a/src/Text/LParse/Atomics.hs b/src/Text/LParse/Atomics.hs
--- a/src/Text/LParse/Atomics.hs
+++ b/src/Text/LParse/Atomics.hs
@@ -69,3 +69,15 @@
 -- | Succeeds if the first token matches the given function, without consuming it
 peek :: (TokenStream s) => (t -> Bool) -> String -> Parser r (s t) ()
 peek c = cParse (c . top) noop
+
+-- | A parser that always succeeds with the given function
+success :: (t -> (a,t)) -> Parser r t a
+success = Parser . (return .)
+
+-- | Parses an integer by removing a single digit in the given base from it. Zero is considered to have no digits
+bDigit :: Integer -> Parser r Integer Integer
+bDigit b = cParse (> 0) (success (\i -> (i `mod` b,i `div` b))) "Empty number!"
+
+-- | Parses an integer by removing a single digit in the given base from it. Zero is considered to have no digits
+bDigits :: Integer -> Parser r Integer [Integer]
+bDigits b = many $ bDigit b
diff --git a/src/Text/LParse/TokenStream.hs b/src/Text/LParse/TokenStream.hs
--- a/src/Text/LParse/TokenStream.hs
+++ b/src/Text/LParse/TokenStream.hs
@@ -9,6 +9,7 @@
 -}
 module Text.LParse.TokenStream where 
 
+import Data.Either
 import Data.Maybe
 import Data.Traversable
 
@@ -36,6 +37,12 @@
     rest = const Nothing
     nil = Nothing
     cons a _ = Just a
+
+instance TokenStream (Either a) where
+    top = head . rights . return
+    rest x = if isLeft x then x else nil
+    nil = Left undefined
+    cons a _ = Right a
 
 -- | Deprecated version of `sDrop`
 skipN :: (TokenStream s) => Int -> s a -> s a
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -1,72 +1,87 @@
-module Main where 
-
-import Text.LParse.Parser
-import Text.LParse.Atomics
-import Text.LParse.Transformers
-
-import Control.Applicative
-import Control.Monad
-import Data.Either
-import Data.List
-import Data.Maybe
-import System.Exit (exitSuccess,exitFailure)
-
-succCases :: [(Parser r String (),String)]
-succCases = [
-    (noop,""),
-    (eoi,""),
-    (discard,"lel"),
-    (discard >> eoi,"lorem ipsum"),
-    (consume "prefix","prefixed"),
-    (consume "", "foo"),
-    (consume "", ""),
-    (letter >> eoi, "b"),
-    (digit >> eoi, "4"),
-    (word >> eoi, "banana")
-    ]
-
-failCases :: [(Parser r String (),String)]
-failCases = [
-    (eoi,"foo"),
-    (consume "prefix", "freepix"),
-    (consume "prefix", ""),
-    (letter >> eoi, "banana"),
-    (digit >> eoi, "42"),
-    (word >> eoi, "banana bread")
-    ]
-
-stringCases :: [(Parser r String String, String, String)]
-stringCases = [
-    (word,"sufficient example","sufficient")
-    ]
-
-intCases :: [(Parser r String Integer, String, Integer)]
-intCases = [
-    (integer,"123 is a nice number",123),
-    (digit,"123 is a nice number",1),
-    (sum <$> sepMany (consume " ") integer,"1 4 12 61 192",1+4+12+61+192)
-    ]
-
-runTests :: [(Parser (Either String a) t a,t)] -> [Either String a]
-runTests = map (uncurry doParse)
-
-eqTest :: (Eq a, Show a) => (Parser (Either String ()) t a, t, a) -> Either String ()
-eqTest (p,i,e) = parse p i (\r -> if r == e then Right () else Left ("Expected " ++ show e ++ ", but got " ++ show r)) (const $ Left "Parser error")
-
-succTest :: [Either String a] -> IO ()
-succTest res = if all isRight res then return () else putStrLn (head $ lefts res) >> exitFailure
-
-failTest :: [Either String a] -> IO ()
-failTest res = if all isLeft res then return () else putStrLn "Fail Test Succeeded" >> exitFailure
-
-main ::IO ()
-main = do
-    let sres = runTests succCases
-    let fres = runTests failCases
-    let seres = map eqTest stringCases
-    let ieres = map eqTest intCases
-    succTest sres
-    failTest fres
-    succTest seres
-    succTest ieres
+module Main where 
+
+import Text.LParse.Parser
+import Text.LParse.Atomics
+import Text.LParse.Transformers
+
+import Control.Applicative
+import Control.Arrow
+import Control.Monad
+import Data.Either
+import Data.List
+import Data.Maybe
+import System.Exit (exitSuccess,exitFailure)
+
+bracks :: Parser r String ()
+bracks = (consume "(" >> nesting << consume ")")
+    <|> (consume "[" >> nesting << consume "]")
+    <|> (consume "{" >> nesting << consume "}")
+    <|> (consume "<" >> nesting << consume ">")
+
+nesting :: Parser r String ()
+nesting = void $ many bracks
+
+succCases :: [(Parser r String (),String)]
+succCases = [
+    (noop,""),
+    (eoi,""),
+    (discard,"lel"),
+    (discard >> eoi,"lorem ipsum"),
+    (consume "prefix","prefixed"),
+    (consume "", "foo"),
+    (consume "", ""),
+    (letter >> eoi, "b"),
+    (digit >> eoi, "4"),
+    (word >> eoi, "banana"),
+    (nesting >> eoi, "({()}[])")
+    ]
+
+failCases :: [(Parser r String (),String)]
+failCases = [
+    (eoi,"foo"),
+    (consume "prefix", "freepix"),
+    (consume "prefix", ""),
+    (letter >> eoi, "banana"),
+    (digit >> eoi, "42"),
+    (word >> eoi, "banana bread"),
+    (nesting >> eoi, "({(})[])")
+    ]
+
+stringCases :: [(Parser r String String, String, String)]
+stringCases = [
+    (word,"sufficient example","sufficient"),
+    (integer >>> (show <$> bDigits 2), "19", "[1,1,0,0,1]")
+    ]
+
+intCases :: [(Parser r String Integer, String, Integer)]
+intCases = [
+    (integer,"123 is a nice number",123),
+    (digit,"123 is a nice number",1),
+    (sum <$> sepMany (consume " ") integer,"1 4 12 61 192",1+4+12+61+192),
+    (integer >>> (sum <$> bDigits 2), "19", 3),
+    (integer >>> (foldr (\x y -> x + y * 2) 0 <$> bDigits 2), "19", 19)
+    ]
+
+runTests :: [(Parser (Either String a) t a,t)] -> [Either String a]
+runTests = map (uncurry doParse)
+
+eqTest :: (Eq a, Show a) => (Parser (Either String ()) t a, t, a) -> Either String ()
+eqTest (p,i,e) = parse p i (\r -> if r == e then Right () else Left ("Expected " ++ show e ++ ", but got " ++ show r)) (const $ Left "Parser error")
+
+succTest :: [Either String a] -> IO ()
+succTest res = if all isRight res then return () else putStrLn (head $ lefts res) >> exitFailure
+
+failTest :: [Either String a] -> IO ()
+failTest res = if all isLeft res then return () else putStrLn "Fail Test Succeeded" >> exitFailure
+
+main ::IO ()
+main = do
+    let sres = runTests succCases
+    let fres = runTests failCases
+    let seres = map eqTest stringCases
+    let ieres = map eqTest intCases
+    succTest sres
+    failTest fres
+    succTest seres
+    succTest ieres
     exitSuccess
