diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,346 @@
+# inline-c
+
+[![Build Status](https://travis-ci.org/fpco/inline-c.svg)](https://travis-ci.org/fpco/inline-c)
+
+`inline-c` lets you seamlessly call C libraries and embed
+high-performance inline C code in Haskell modules. Haskell and C can
+be freely intermixed in the same source file, and data passed to and
+from code in either language with minimal overhead. No FFI required.
+
+`inline-c` is Haskell's escape hatch (or one of) to the wild world of
+legacy code and high-performance numerical and system libraries. It
+has other uses too: you can also think of `inline-c` as to Haskell
+what inline Assembly is to C — a convenient means to eke out a little
+bit of extra performance in those rare cases where C still beats
+Haskell.
+
+Build instructions are reserved for the [last section](#how-to-build).
+You'll need to compile the examples below and try them out.
+
+## Getting started
+
+Let's say we want to compute the cosine of a number using C from
+Haskell. `inline-c` let's you write this function call inline, without
+any need for a binding to the foreign function:
+
+```
+{-# LANGUAGE QuasiQuotes #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+import qualified Language.C.Inline as C
+
+C.include "<math.h>"
+
+main :: IO ()
+main = do
+  x <- [C.exp| double{ cos(1) } |]
+  print x
+```
+
+`inline-c` leverages the [quasiquotation][ghc-manual-quasiquotation]
+language extension implemented in GHC.
+[Template Haskell][ghc-manual-template-haskell] is also required.
+Importing the `Language.C.Inline` module brings in scope most required
+Haskell definitions. `C.include "<math.h>"` brings into scope the
+foreign function `cos()` that we wish to call. Finally, in the `main`
+function, `[C.exp| double { cos(1) } |]` denotes an inline C expression
+of type `double`. `cexp` stands for "C expression". It is a custom
+quasiquoter provided by `inline-c`.
+
+A `C.exp` quasiquotation always includes a type annotation for the
+inline C expression. This annotation determines the type of the
+quasiquotation in Haskell. Out of the box, `inline-c` knows how to map
+many common C types to Haskell type. In this case,
+
+```
+[C.exp| double { cos(1) } |] :: IO CDouble
+```
+
+For pure C expression like these we also provide `C.pure`, which works
+exactly the same but without the `IO`:
+
+```
+[C.pure| double { cos(1) } |] :: CDouble
+```
+
+Obviously extra care must be taken when using `C.pure`: the embedded C
+code must be referentially transparent.
+
+## Multiple statements
+
+`inline-c` allows embedding arbitrary C code, not just expressions, in
+the form of a sequence of statements, using the `c` quasiquoter:
+
+```
+{-# LANGUAGE QuasiQuotes #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+import qualified Language.C.Inline as C
+
+C.include "<stdio.h>"
+
+main :: IO ()
+main = do
+  x <- [C.block| int {
+      // Read and sum 5 integers
+      int i, sum = 0, tmp;
+      for (i = 0; i < 5; i++) {
+        scanf("%d ", &tmp);
+        sum += tmp;
+      }
+      return sum;
+    } |]
+  print x
+```
+
+Just as with `C.exp`, we need a type annotation on the entire C block.
+The annotation specifies the return type. That is, the type of the
+expression in any return statement.
+
+## Capturing Haskell variables -- parameter declaration
+
+`inline-c` allows referring to Haskell variables inside C expressions
+and code blocks. We do so by "anti-quoting" them.
+
+Let's say that we wanted to parameterize the function we wrote above
+by how many numbers we should read. We can do so by defining a Haskell
+function whose parameter we can refer to from within C:
+
+```
+{-# LANGUAGE QuasiQuotes #-}
+{-# LANGUAGE TemplateHaskell #-}
+import qualified Language.C.Inline as C
+import           Foreign.C.Types
+
+C.include "<stdio.h>"
+
+-- | @readAndSum n@ reads @n@ numbers from standard input and returns
+-- their sum.
+readAndSum :: CInt -> IO CInt
+readAndSum n  = [C.block| int {
+    // Read and sum n integers
+    int i, sum = 0, tmp;
+    for (i = 0; i < $(int n); i++) {
+      scanf("%d ", &tmp);
+      sum += tmp;
+    }
+    return sum;
+  } |]
+
+main :: IO ()
+main = do
+  x <- readAndSum 5
+  print x
+```
+
+Here, the Haskell variable `n` is captured right where we need it using
+`$(int n)`.  Standard anti-quotation (we'll talk about additional ones
+later) consists of a `$` followed by a C declaration in parenthesis.
+
+For each anti-quotation, a variable with a matching type is expected in
+the Haskell environment.  In this case `inline-c` expects a variable
+named `n` of type `CInt`, which is the case.
+
+## What can be captured and returned?
+
+All C types correspond to exactly one Haskell type. Basic types (`int`,
+`long`, `double`, `float`, etc.) get converted to their Haskell
+equivalents `CInt`, `CLong`, `CDouble`, `CFloat`. Pointers and arrays
+get converted to `Ptr`. Function pointers get converted to `FunPtr`.
+
+`inline-c` can also handle user-defined structs and enums, provided that
+they are instances of `Storable` and that you tell `inline-c` about them
+using [contexts](#contexts).
+
+## Contexts
+
+Everything beyond the base functionality provided by `inline-c` is
+specified in a structure that we call "`Context`".  From a user
+perspective, if we want to use anything but the default context
+(`C.baseCtx`), we must set the `C.Context` explicitly using the
+`C.context` function.  The next two sections include several examples.
+
+The `C.Context` allows to extend `inline-c` to support
+
+* Custom C types beyond the basic ones;
+* And [additional anti-quoters](#more-anti-quoters).
+
+`C.Context`s can be composed using their `Monoid` instance.
+
+Ideally a `C.Context` will be provided for each C library that should be
+used with `inline-c`. The user can then combine multiple contexts
+together if multiple libraries are to be used in the same program. See
+the [`inline-c-nag` package](https://github.com/fpco/inline-c-nag) for
+an example of using a `C.Context` tailored for a library.
+
+For information regarding how to define `C.Context`s, see the
+Haddock-generated API documentation for `Language.C.Inline.Context`.
+
+## More anti-quoters
+
+Besides the basic anti-quoter, which captures variables as they are,
+some more anti-quoters are provided with additional functionality.  As
+mentioned, `inline-c` can easily be extended with anti-quoters defined
+by the user, using [contexts](#contexts).
+
+### Vectors
+
+The `vec-len` and `vec-ptr` anti-quoters in the `C.vecCtx` context let us
+easily use [Haskell vectors](http://hackage.haskell.org/package/vector)
+in C.  Continuing along the "summing" theme, we can write code that sums
+Haskell vectors in C:
+
+```
+{-# LANGUAGE QuasiQuotes #-}
+{-# LANGUAGE TemplateHaskell #-}
+import qualified Language.C.Inline as C
+import qualified Data.Vector.Storable.Mutable as V
+import           Data.Monoid ((<>))
+import           Foreign.C.Types
+
+-- To use the vector anti-quoters, we need the 'C.vecCtx' along with the
+-- 'C.baseCtx'.
+C.context (C.baseCtx <> C.vecCtx)
+
+sumVec :: V.IOVector CDouble -> IO CDouble
+sumVec vec = [C.block| double {
+    double sum = 0;
+    int i;
+    for (i = 0; i < $vec-len:vec; i++) {
+      sum += $vec-ptr:(double *vec)[i];
+    }
+    return sum
+  } |]
+
+main :: IO ()
+main = do
+  x <- sumVec =<< V.fromList [1,2,3]
+  print x
+```
+
+The `vec-len` anti-quoter is used simply by specifying the vector we
+want to get the length of (in our case, `vec`).  To use the `vec-ptr`
+anti-quoter it is also required to specify the pointer type we want.
+Since `vec` is a vector of `CDouble`s, we want a pointer to `double`s.
+
+## ByteStrings
+
+The `bs-len` and `bs-ptr` ant-quoters in the `C.bsCtx` context work
+exactly the same as the `vec-len` and `vec-ptr` counterparts, but with
+strict `ByteString`s.  The only difference is that it is no necessary to
+specify the type of the pointer from C -- it is always going to be
+`unsigned char *`:
+
+```
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE QuasiQuotes #-}
+import qualified Data.ByteString as BS
+import           Data.Monoid ((<>))
+import           Foreign.C.Types
+import qualified Language.C.Inline as C
+
+C.context (C.baseCtx <> C.bsCtx)
+
+-- | Count the number of set bits in a 'BS.ByteString'.
+countSetBits :: BS.ByteString -> IO CInt
+countSetBits bs = [C.block|
+    int {
+      int i, bits = 0;
+      for (i = 0; i < $bs-len:bs; i++) {
+        unsigned char ch = $bs-ptr:bs[i];
+        bits += (ch * 01001001001ULL & 042104210421ULL) % 017;
+      }
+      return bits;
+    }
+  |]
+```
+
+### Function pointers
+
+Using the `fun` anti-quoter, present in the `C.funCtx` context, we can
+easily turn Haskell function into function pointers.
+
+```
+{-# LANGUAGE QuasiQuotes #-}
+{-# LANGUAGE TemplateHaskell #-}
+import qualified Language.C.Inline as C
+
+-- To use the function pointer anti-quoter, we need the 'C.funCtx along with
+-- the 'C.baseCtx'.
+C.context (C.baseCtx <> C.funCtx)
+
+ackermann :: CLong -> CLong -> CLong
+ackermann m n
+  | m == 0 = n + 1
+  | m > 0 && n == 0 = ackermann (m - 1) 1
+  | otherwise = ackermann (m - 1) (ackermann m (n - 1))
+
+main :: IO ()
+main = do
+  let ackermannIO m n = return $ ackermann m n
+  let x = 3
+  let y = 4
+  z <- [C.exp| long{
+      $fun:(int (*ackermannIO)(int, int))($(long x), $(long y))
+    } |]
+  print z
+```
+
+In this example, we capture a Haskell function of type `CLong -> CLong
+-> IO CLong`, `ackermannIO`, to a function pointer in C, using the `fun`
+anti-quoter.  Note how we need to specify the function pointer type when
+we capture `ackermannIO`, using standard C declaration syntax.  Also
+note that the `fun` anti-quoter works with `IO` functions, and so we
+needed to modify `ackermann` to make it have the right type.
+
+In general, when anti-quoting, if the type can be inferred (like in the
+case of `vec-len`), only the Haskell identifier appears.  If it can't,
+the target C type and the Haskell identifier are mentioned using C
+declaration syntax.
+
+## How to build
+
+Each module that uses at least one of the `inline-c` functions gets a C
+file associated to it, where the filename of said file will be the same
+as the module but with a C extension.  This C file must be built after
+the Haskell code and linked appropriately.  If you use cabal, all you
+have to do is declare each associated C file in the `.cabal` file and
+you are good.
+
+For example we might have
+
+```
+executable foo
+  main-is:             Main.hs, Foo.hs, Bar.hs
+  hs-source-dirs:      src
+  -- Here the corresponding C sources must be listed for every module
+  -- that uses C code.  In this example, Main.hs and Bar.hs do, but
+  -- Foo.hs does not.
+  c-sources:           src/Main.c, src/Bar.c
+  -- These flags will be passed to the C compiler
+  cc-options:          -Wall -O2
+  -- Libraries to link the code with.
+  extra-libraries:     -lm
+  ...
+```
+
+Note that currently `cabal repl` is not supported, because the C code is
+not compiled and linked appropriately.  Type-checking will still be
+performed, so `cabal repl` can still be used to develop.
+
+See `sample-cabal-project` for a working example.
+
+If we were to compile the above manually we could do:
+
+```
+$ ghc -c Main.hs
+$ cc -c Main.c -o Main_c.o
+$ ghc Foo.hs
+$ ghc Bar.hs
+$ cc -c Bar.c -o Bar_c.o
+$ ghc Main.o Foo.o Bar.o Main_c.o Bar_c.o -lm -o Main
+```
+
+[ghc-manual-quasiquotation]:
+https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/template-haskell.html#th-quasiquotation
+[ghc-manual-template-haskell]: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/template-haskell.html
diff --git a/changelog.md b/changelog.md
new file mode 100644
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,2 @@
+- 0.5.2.0: Make `bs-ptr` use `char` instead of `unsigned char`.  See
+  issue #16.
diff --git a/inline-c.cabal b/inline-c.cabal
--- a/inline-c.cabal
+++ b/inline-c.cabal
@@ -1,5 +1,5 @@
 name:                inline-c
-version:             0.5.0.1
+version:             0.5.2.0
 synopsis:            Write Haskell source files including C code inline. No FFI required.
 description:         See <https://github.com/fpco/inline-c/blob/master/README.md>.
 license:             MIT
@@ -11,6 +11,7 @@
 tested-with:         GHC == 7.8.4, GHC == 7.10.1
 build-type:          Simple
 cabal-version:       >=1.10
+Extra-Source-Files:  README.md, changelog.md
 
 source-repository head
   type:     git
diff --git a/src/Language/C/Inline/Context.hs b/src/Language/C/Inline/Context.hs
--- a/src/Language/C/Inline/Context.hs
+++ b/src/Language/C/Inline/Context.hs
@@ -52,7 +52,7 @@
 import qualified Data.Vector.Storable as V
 import qualified Data.Vector.Storable.Mutable as VM
 import           Foreign.C.Types
-import           Foreign.Ptr (Ptr, FunPtr, castPtr)
+import           Foreign.Ptr (Ptr, FunPtr)
 import           Foreign.Storable (Storable)
 import qualified Language.Haskell.TH as TH
 import qualified Text.Parser.Token as Parser
@@ -377,13 +377,13 @@
   { aqParser = do
       cId <- C.parseIdentifier
       let s = C.unIdentifier cId
-      return (s, C.Ptr [] (C.TypeSpecifier mempty (C.Char (Just C.Unsigned))), s)
+      return (s, C.Ptr [] (C.TypeSpecifier mempty (C.Char Nothing)), s)
   , aqMarshaller = \_purity _cTypes cTy cId -> do
       case cTy of
-        C.Ptr _ (C.TypeSpecifier _ (C.Char (Just C.Unsigned))) -> do
-          hsTy <- [t| Ptr CUChar |]
+        C.Ptr _ (C.TypeSpecifier _ (C.Char Nothing)) -> do
+          hsTy <- [t| Ptr CChar |]
           hsExp <- getHsVariable "bsCtx" cId
-          hsExp' <- [| \cont -> BS.unsafeUseAsCString $(return hsExp) $ \ptr -> cont (castPtr ptr)  |]
+          hsExp' <- [| \cont -> BS.unsafeUseAsCString $(return hsExp) $ \ptr -> cont ptr  |]
           return (hsTy, hsExp')
         _ ->
           error "impossible: got type different from `unsigned char' (bsCtx)"
diff --git a/test/tests.c b/test/tests.c
--- a/test/tests.c
+++ b/test/tests.c
@@ -94,3 +94,15 @@
       
 }
 
+
+int inline_c_14_17d13d6f2f87c2401476aaf41e06593689723baf(long bs_inline_c_0, char * bs_inline_c_1) {
+
+          int i, bits = 0;
+          for (i = 0; i < bs_inline_c_0; i++) {
+            char ch = bs_inline_c_1[i];
+            bits += (ch * 01001001001ULL & 042104210421ULL) % 017;
+          }
+          return bits;
+        
+}
+
diff --git a/test/tests.hs b/test/tests.hs
--- a/test/tests.hs
+++ b/test/tests.hs
@@ -19,7 +19,7 @@
 
 import           Dummy
 
-C.context (C.baseCtx <> C.funCtx <> C.vecCtx)
+C.context (C.baseCtx <> C.funCtx <> C.vecCtx <> C.bsCtx)
 
 C.include "<math.h>"
 C.include "<stdio.h>"
@@ -156,3 +156,15 @@
         return x;
       } |]
       sum' `Hspec.shouldBe` 3 * 10
+    Hspec.it "bytestrings" $ do
+      let bs = "foo"
+      bits <- [C.block| int {
+          int i, bits = 0;
+          for (i = 0; i < $bs-len:bs; i++) {
+            char ch = $bs-ptr:bs[i];
+            bits += (ch * 01001001001ULL & 042104210421ULL) % 017;
+          }
+          return bits;
+        } |]
+      bits `Hspec.shouldBe` 16
+
