diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+# operational-alacarte
+
+A version of Operational suitable for EDSLs extensible via data types à la carte. For more information, see the [source code documentation](http://hackage.haskell.org/package/operational-alacarte/docs/Control-Monad-Operational-Higher.html).
+
+[![Build Status](https://travis-ci.org/emilaxelsson/operational-alacarte.png)](https://travis-ci.org/emilaxelsson/operational-alacarte)
diff --git a/examples/Advanced.hs b/examples/Advanced.hs
new file mode 100644
--- /dev/null
+++ b/examples/Advanced.hs
@@ -0,0 +1,166 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE TypeOperators #-}
+
+{-# OPTIONS_GHC -fno-warn-missing-methods #-}
+
+module Advanced where
+
+import Data.IORef
+
+import Control.Monad.Operational.Higher
+
+
+
+-- This file is a version of `Simple.hs` where we want to expose the fact that
+-- programs have expressions as sub-structures. To do this, we use instructions
+-- with types of the form
+--
+--     instr (Param2 p e) a
+--
+-- where `p` represents sub-programs and `e` represents expressions.
+--
+-- The `Program` type is now specialized to `Program ... '[Exp]`.
+--
+-- By exposing expressions in this way, we decouple the interpretation of
+-- instructions from that of expressions. This can be seen in the example below
+-- which defines
+--
+--     main = fmap eval $ interpretBi (return . eval) prog
+--
+-- The interpretation of instructions is obtained from the `InterpBi` class,
+-- while the interpretation of expressions is provided separately.
+
+
+
+--------------------------------------------------------------------------------
+-- Simple expression language
+--------------------------------------------------------------------------------
+
+data Exp a
+  where
+    Lit :: a -> Exp a
+    Add :: Num a => Exp a -> Exp a -> Exp a
+    Eq  :: Eq a => Exp a -> Exp a -> Exp Bool
+
+instance Num a => Num (Exp a)
+  where
+    fromInteger = Lit . fromInteger
+    (+) = Add
+
+eval :: Exp a -> a
+eval (Lit i)   = i
+eval (Add a b) = eval a + eval b
+eval (Eq a b)  = eval a == eval b
+
+
+
+--------------------------------------------------------------------------------
+-- Composable instructions
+--------------------------------------------------------------------------------
+
+data Val a = Val a
+
+-- | If statement
+data If fs a
+  where
+    If :: e Bool -> p a -> p a -> If (Param2 p e) a
+
+-- | Loop
+data Loop fs a
+  where
+    Loop :: e Int -> p () -> Loop (Param2 p e) ()
+
+-- | Mutable references
+data Ref fs a
+  where
+    NewRef :: e a -> Ref (Param2 p e) (IORef a)
+    GetRef :: IORef a -> Ref (Param2 p e) (Val a)
+    SetRef :: IORef a -> e a -> Ref (Param2 p e) ()
+  -- Note: `GetRef` cannot return `exp a` as that would prevent writing the
+  -- `HBifunctor` instance.
+
+instance HFunctor If
+  where
+    hfmap f (If c thn els) = If c (f thn) (f els)
+
+instance HFunctor Loop
+  where
+    hfmap f (Loop n body) = Loop n (f body)
+
+instance HFunctor Ref
+  where
+    hfmap f (NewRef a)   = NewRef a
+    hfmap f (GetRef r)   = GetRef r
+    hfmap f (SetRef r a) = SetRef r a
+
+instance HBifunctor If
+  where
+    hbimap f g (If c thn els) = If (g c) (f thn) (f els)
+
+instance HBifunctor Loop
+  where
+    hbimap f g (Loop n body) = Loop (g n) (f body)
+
+instance HBifunctor Ref
+  where
+    hbimap _ g (NewRef a)   = NewRef (g a)
+    hbimap _ g (GetRef r)   = GetRef r
+    hbimap _ g (SetRef r a) = SetRef r (g a)
+
+instance InterpBi If IO fs
+  where
+    interpBi (If c thn els) = c >>= \c' -> if c' then thn else els
+
+instance InterpBi Loop IO fs
+  where
+    interpBi (Loop n body) = n >>= \n' -> replicateM_ n' body
+
+instance InterpBi Ref IO fs
+  where
+    interpBi (NewRef a)   = newIORef =<< a
+    interpBi (GetRef r)   = fmap Val $ readIORef r
+    interpBi (SetRef r a) = writeIORef r =<< a
+
+
+
+--------------------------------------------------------------------------------
+-- Example
+--------------------------------------------------------------------------------
+
+type MyProgram a = Program (If :+: Loop :+: Ref) (Param1 Exp) a
+
+iff :: Exp Bool -> MyProgram a -> MyProgram a -> MyProgram a
+iff c thn els = singleInj $ If c thn els
+
+loop :: Exp Int -> MyProgram () -> MyProgram ()
+loop n = singleInj . Loop n
+
+newRef :: Exp a -> MyProgram (IORef a)
+newRef = singleInj . NewRef
+
+getRef :: IORef a -> MyProgram (Exp a)
+getRef r = do
+    Val a <- singleInj $ GetRef r
+    return $ Lit a
+
+setRef :: IORef a -> Exp a -> MyProgram ()
+setRef r = singleInj . SetRef r
+
+prog :: MyProgram (Exp Int)
+prog = do
+    r <- newRef 0
+    loop 10 $ do
+        a <- getRef r
+        iff (Eq a 3)
+            (setRef r 100)
+            (setRef r (a+1))
+    getRef r
+
+main = fmap eval $ interpretBi (return . eval) prog
+
diff --git a/examples/Simple.hs b/examples/Simple.hs
new file mode 100644
--- /dev/null
+++ b/examples/Simple.hs
@@ -0,0 +1,137 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE TypeOperators #-}
+
+{-# OPTIONS_GHC -fno-warn-missing-methods #-}
+
+module Simple where
+
+import Data.IORef
+
+import Control.Monad.Operational.Higher
+
+
+
+-- This file demonstrates simple use of the library. Instructions have types of
+-- the form
+--
+--     instr '[p] a
+--
+-- where `p` represents sub-programs.
+--
+-- The `Program` type is specialized to `Program ... '[]`, which means that
+-- we're not interested in exposing any sub-structures of programs.
+
+
+
+--------------------------------------------------------------------------------
+-- Simple expression language
+--------------------------------------------------------------------------------
+
+data Exp a
+  where
+    Lit :: a -> Exp a
+    Add :: Num a => Exp a -> Exp a -> Exp a
+    Eq  :: Eq a => Exp a -> Exp a -> Exp Bool
+
+instance Num a => Num (Exp a)
+  where
+    fromInteger = Lit . fromInteger
+    (+) = Add
+
+eval :: Exp a -> a
+eval (Lit i)   = i
+eval (Add a b) = eval a + eval b
+eval (Eq a b)  = eval a == eval b
+
+
+
+--------------------------------------------------------------------------------
+-- Composable instructions
+--------------------------------------------------------------------------------
+
+-- | If statement
+data If p a
+  where
+    If :: Exp Bool -> p a -> p a -> If (Param1 p) a
+
+-- | Loop
+data Loop p a
+  where
+    Loop :: Exp Int -> p () -> Loop (Param1 p) ()
+
+-- | Mutable references
+data Ref p a
+  where
+    NewRef :: Exp a -> Ref (Param1 p) (IORef a)
+    GetRef :: IORef a -> Ref (Param1 p) (Exp a)
+    SetRef :: IORef a -> Exp a -> Ref (Param1 p) ()
+
+instance HFunctor If
+  where
+    hfmap f (If c thn els) = If c (f thn) (f els)
+
+instance HFunctor Loop
+  where
+    hfmap f (Loop n body) = Loop n (f body)
+
+instance HFunctor Ref
+  where
+    hfmap f (NewRef a)   = NewRef a
+    hfmap f (GetRef r)   = GetRef r
+    hfmap f (SetRef r a) = SetRef r a
+
+instance Interp If IO fs
+  where
+    interp (If c thn els) = if eval c then thn else els
+
+instance Interp Loop IO fs
+  where
+    interp (Loop n body) = replicateM_ (eval n) body
+
+instance Interp Ref IO fs
+  where
+    interp (NewRef a)   = newIORef (eval a)
+    interp (GetRef r)   = fmap Lit $ readIORef r
+    interp (SetRef r a) = writeIORef r (eval a)
+
+
+
+--------------------------------------------------------------------------------
+-- Example
+--------------------------------------------------------------------------------
+
+type MyProgram = Program (If :+: Loop :+: Ref) Param0
+
+iff :: Exp Bool -> MyProgram a -> MyProgram a -> MyProgram a
+iff c thn els = singleInj $ If c thn els
+
+loop :: Exp Int -> MyProgram () -> MyProgram ()
+loop n = singleInj . Loop n
+
+newRef :: Exp a -> MyProgram (IORef a)
+newRef = singleInj . NewRef
+
+getRef :: IORef a -> MyProgram (Exp a)
+getRef = singleInj . GetRef
+
+setRef :: IORef a -> Exp a -> MyProgram ()
+setRef r = singleInj . SetRef r
+
+prog :: MyProgram (Exp Int)
+prog = do
+    r <- newRef 0
+    loop 10 $ do
+        a <- getRef r
+        iff (Eq a 3)
+            (setRef r 100)
+            (setRef r (a+1))
+    getRef r
+
+main = fmap eval $ interpret prog
+
diff --git a/operational-alacarte.cabal b/operational-alacarte.cabal
--- a/operational-alacarte.cabal
+++ b/operational-alacarte.cabal
@@ -1,5 +1,5 @@
 name:                operational-alacarte
-version:             0.3
+version:             0.3.1
 synopsis:            A version of Operational suitable for extensible EDSLs
 description:         A version of Operational \[1\] suitable for EDSLs
                      extensible via data types à la carte.
@@ -22,7 +22,7 @@
 license:             BSD3
 license-file:        LICENSE
 author:              Emil Axelsson
-maintainer:          emax@chalmers.se
+maintainer:          78emil@gmail.com
 copyright:           Copyright (c) 2016 Emil Axelsson
                      Copyright (c) 2015 Emil Axelsson, Heinrich Apfelmus
 homepage:            https://github.com/emilaxelsson/operational-alacarte
@@ -31,6 +31,11 @@
 build-type:          Simple
 cabal-version:       >=1.10
 
+extra-source-files:
+  README.md
+  examples/*.hs
+  tests/*.hs
+
 source-repository head
   type:     git
   location: git@github.com:emilaxelsson/operational-alacarte.git
@@ -58,7 +63,7 @@
     -- DeriveDataTypeable only needed for GHC < 7.10
 
   build-depends:
-    base >=4 && <5,
+    base >=4.6 && <5,
     mtl
 
   hs-source-dirs: src
