diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 0.1.2.1
+
+  * Restyle
+
 # 0.1.2.0
 
   * Add some higher-level functions for dealing with captures
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,4 +1,22 @@
 Bindings to Rust's [regular expression library](https://github.com/rust-lang/regex). See [here](https://github.com/rust-lang/regex/tree/master/regex-capi#c-api-for-rusts-regex-engine) for installation instructions. You'll need to put `librure.so` or `librure.dylib` etc. where libraries go on your system.
 
-Lower-level bindings are exhaustive; higher-level bindings no not include
+Lower-level bindings are exhaustive; higher-level bindings do not include
 capture groups.
+
+# Performance
+
+As of 0.1.0.3:
+
+```
+benchmarking rure/matches
+time                 334.6 ns   (334.1 ns .. 335.2 ns)
+                     1.000 R²   (1.000 R² .. 1.000 R²)
+mean                 333.8 ns   (333.5 ns .. 334.2 ns)
+std dev              1.247 ns   (1.058 ns .. 1.649 ns)
+
+benchmarking tdfa/matches
+time                 1.180 μs   (1.180 μs .. 1.181 μs)
+                     1.000 R²   (1.000 R² .. 1.000 R²)
+mean                 1.179 μs   (1.179 μs .. 1.180 μs)
+std dev              2.029 ns   (1.607 ns .. 2.851 ns)
+```
diff --git a/regex-rure.cabal b/regex-rure.cabal
--- a/regex-rure.cabal
+++ b/regex-rure.cabal
@@ -1,6 +1,6 @@
 cabal-version:      1.18
 name:               regex-rure
-version:            0.1.2.0
+version:            0.1.2.1
 license:            AGPL-3
 license-file:       COPYING
 maintainer:         vamchale@gmail.com
@@ -12,9 +12,10 @@
 category:           Text, Regex
 build-type:         Simple
 extra-source-files:
-    CHANGELOG.md
     README.md
     cbits/rure.h
+
+extra-doc-files:    CHANGELOG.md
 
 source-repository head
     type:     git
diff --git a/src/Regex/Rure.chs b/src/Regex/Rure.chs
--- a/src/Regex/Rure.chs
+++ b/src/Regex/Rure.chs
@@ -50,13 +50,17 @@
 
 #include <rure.h>
 
+infixr 9 ?
+infixr 9 ??
+
+x ? b = if b then x else pure Nothing
+x ?? b = (Just<$>x) ? b
+
 capturesAt :: RureCapturesPtr -> CSize -> IO (Maybe RureMatch)
 capturesAt rcp sz =
     allocaBytes {# sizeof rure_match #} $ \matchPtr -> do
     res <- rureCapturesAt rcp sz matchPtr
-    if res
-        then Just <$> rureMatchFromPtr matchPtr
-        else pure Nothing
+    rureMatchFromPtr matchPtr ?? res
 
 {-# DEPRECATED mkIter "This creates a stateful pointer in an otherwise pure API" #-}
 mkIter :: RurePtr -> IO RureIterPtr
@@ -119,21 +123,16 @@
         -> BS.ByteString
         -> IO [RureMatch]
 matches reIPtr haystack = do
-    res <- iterNext reIPtr haystack
+    res <- next
     case res of
         Nothing -> pure []
-        Just m -> (m :) <$> matches reIPtr haystack
-
-iterNext :: RureIterPtr
-         -> BS.ByteString
-         -> IO (Maybe RureMatch)
-iterNext reIPtr haystack =
-    allocaBytes {# sizeof rure_match #} $ \matchPtr -> do
+        Just m -> (m:) <$> matches reIPtr haystack
+  where
+    next :: IO (Maybe RureMatch)
+    next = allocaBytes {# sizeof rure_match #} $ \matchPtr -> do
         res <- BS.unsafeUseAsCStringLen haystack $ \(p, sz) ->
             rureIterNext reIPtr (castPtr p) (fromIntegral sz) matchPtr
-        if res
-            then Just <$> rureMatchFromPtr matchPtr
-            else pure Nothing
+        rureMatchFromPtr matchPtr ?? res
 
 rureMatchFromPtr :: Ptr RureMatch -> IO RureMatch
 rureMatchFromPtr matchPtr =
@@ -162,33 +161,26 @@
          -> BS.ByteString
          -> CSize -- ^ Index (for captures)
          -> IO [RureMatch]
-captures re haystack ix = do
+captures re haystack n = do
     capPtr <- allocCapPtr re
     reIPtr <- mkIter re
-    capturesLoop capPtr reIPtr haystack ix
-
-capturesLoop :: RureCapturesPtr -- ^ For results
-             -> RureIterPtr
-             -> BS.ByteString
-             -> CSize -- ^ Index (captures)
-             -> IO [RureMatch]
-capturesLoop capPtr reIPtr haystack ix = do
-    res <- iterNextCaptures capPtr reIPtr haystack ix
-    case res of
-        Nothing -> pure []
-        Just m -> (m :) <$> capturesLoop capPtr reIPtr haystack ix
-
-iterNextCaptures :: RureCapturesPtr -- ^ For results
-                 -> RureIterPtr
-                 -> BS.ByteString
-                 -> CSize -- ^ Index (captures)
-                 -> IO (Maybe RureMatch)
-iterNextCaptures capPtr reIPtr haystack ix = do
-    res <- BS.unsafeUseAsCStringLen haystack $ \(p, sz) ->
-        rureIterNextCaptures reIPtr (castPtr p) (fromIntegral sz) capPtr
-    if res
-        then capturesAt capPtr ix
-        else pure Nothing
+    loop capPtr reIPtr
+  where
+    loop :: RureCapturesPtr -- ^ For results
+         -> RureIterPtr
+         -> IO [RureMatch]
+    loop capPtr reIPtr = do
+        res <- next n
+        case res of
+            Nothing -> pure []
+            Just m -> (m:) <$> loop capPtr reIPtr
+      where
+        next :: CSize -- ^ Index (captures)
+             -> IO (Maybe RureMatch)
+        next ix = do
+            res <- BS.unsafeUseAsCStringLen haystack $ \(p, sz) ->
+                rureIterNextCaptures reIPtr (castPtr p) (fromIntegral sz) capPtr
+            capturesAt capPtr ix ? res
 
 -- | @since 0.1.2.0
 findCaptures :: RurePtr
@@ -200,9 +192,7 @@
     capFp <- allocCapPtr rp
     res <- BS.unsafeUseAsCStringLen haystack $ \(p, sz) ->
         rureFindCaptures rp (castPtr p) (fromIntegral sz) start' capFp
-    if res
-        then capturesAt capFp ix
-        else pure Nothing
+    capturesAt capFp ix ? res
 
 find :: RurePtr
      -> BS.ByteString -- ^ Unicode
@@ -212,9 +202,7 @@
     allocaBytes {# sizeof rure_match #} $ \matchPtr -> do
         res <- BS.unsafeUseAsCStringLen haystack $ \(p, sz) ->
             rureFind rePtr (castPtr p) (fromIntegral sz) start' matchPtr
-        if res
-            then Just <$> rureMatchFromPtr matchPtr
-            else pure Nothing
+        rureMatchFromPtr matchPtr ?? res
 
 {-# NOINLINE hsSetMatches #-}
 hsSetMatches :: RureFlags
@@ -266,9 +254,9 @@
         l <- fromIntegral <$> rureSetLen rsPtr
         allocaBytes l $ \boolPtr -> do
             rureSetMatches rsPtr (castPtr p) (fromIntegral sz) startϵ boolPtr
-            fmap cBoolToBool <$> peekArray l boolPtr
-    where cBoolToBool 0 = False
-          cBoolToBool _ = True
+            map cB <$> peekArray l boolPtr
+    where cB 0 = False
+          cB _ = True
 
 isMatch :: RurePtr
         -> BS.ByteString -- ^ Unicode
