diff --git a/CHANGES.md b/CHANGES.md
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,6 +1,12 @@
 Changes
 =======
 
+0.1.5
+-----
+* Expose Object interface
+* Allow matching prefixes rather than the whole string
+* Add non-greedy repetitions
+
 0.1.4
 -----
 * Completely rewrite the engine. Now it's faster and runs in constant space.
diff --git a/Text/Regex/Applicative.hs b/Text/Regex/Applicative.hs
--- a/Text/Regex/Applicative.hs
+++ b/Text/Regex/Applicative.hs
@@ -18,9 +18,16 @@
     , anySym
     , string
     , reFoldl
+    , Greediness(..)
+    , few
+    , match
     , (=~)
+    , findFirstPrefix
+    , findLongestPrefix
+    , findShortestPrefix
     , module Control.Applicative
     )
     where
+import Text.Regex.Applicative.Types
 import Text.Regex.Applicative.Interface
 import Control.Applicative
diff --git a/Text/Regex/Applicative/Compile.hs b/Text/Regex/Applicative/Compile.hs
--- a/Text/Regex/Applicative/Compile.hs
+++ b/Text/Regex/Applicative/Compile.hs
@@ -4,7 +4,7 @@
 
 import Text.Regex.Applicative.Types
 
-compile :: forall a s r . Regexp s ThreadId a -> (a -> [Thread s r]) -> [Thread s r]
+compile :: forall a s r . RE s a -> (a -> [Thread s r]) -> [Thread s r]
 compile e k = compile2 e k k
 
 -- The whole point of this module is this function, compile2, which needs to be
@@ -18,7 +18,7 @@
 --
 -- compile2 function takes two continuations: one when the match is empty and
 -- one when the match is non-empty. See the "Rep" case for the reason.
-compile2 :: forall a s r . Regexp s ThreadId a -> (a -> [Thread s r]) -> (a -> [Thread s r]) -> [Thread s r]
+compile2 :: forall a s r . RE s a -> (a -> [Thread s r]) -> (a -> [Thread s r]) -> [Thread s r]
 compile2 e =
     case e of
         Eps -> \ke _kn -> ke $ error "empty"
@@ -36,9 +36,15 @@
             \ke kn -> a1 ke kn ++ a2 ke kn
         Fmap f (compile2 -> a) -> \ke kn -> a (ke . f) (kn . f)
         -- This is actually the point where we use the difference between
-        -- continuations. For the inner regexp the empty continuation is a
+        -- continuations. For the inner RE the empty continuation is a
         -- "failing" one in order to avoid non-termination.
-        Rep f b (compile2 -> a) ->
-            let threads b ke kn =
-                    a (\_ -> []) (\v -> let b' = f b v in threads b' kn kn) ++ ke b
+        Rep g f b (compile2 -> a) ->
+            let combine continue stop =
+                    case g of
+                        Greedy -> continue ++ stop
+                        NonGreedy -> stop ++ continue
+                threads b ke kn =
+                    combine
+                        (a (\_ -> []) (\v -> let b' = f b v in threads b' kn kn))
+                        (ke b)
             in threads b
diff --git a/Text/Regex/Applicative/Implementation.hs b/Text/Regex/Applicative/Implementation.hs
deleted file mode 100644
--- a/Text/Regex/Applicative/Implementation.hs
+++ /dev/null
@@ -1,72 +0,0 @@
-{-# LANGUAGE GADTs, TypeFamilies, ViewPatterns, PatternGuards #-}
-module Text.Regex.Applicative.Implementation (match, Regexp(..)) where
-import Prelude
-import Control.Applicative hiding (empty)
-import Control.Monad.State hiding (foldM)
-import Text.Regex.Applicative.StateQueue
-import Control.Monad.ST
-import Text.Regex.Applicative.Types
-import Text.Regex.Applicative.Compile
-
-fresh :: (MonadState m, StateType m ~ ThreadId) => m ThreadId
-fresh = do
-    i <- get
-    put $! i+1
-    return i
-
-renumber :: Regexp s i a -> (Regexp s ThreadId a, ThreadId)
-renumber e = flip runState 1 $ compile e
-  where
-    compile :: Regexp s i a -> State ThreadId (Regexp s ThreadId a)
-    compile e =
-        case e of
-            Eps -> return Eps
-            Symbol _ p -> Symbol <$> fresh <*> pure p
-            Alt a1 a2 -> Alt <$> compile a1 <*> compile a2
-            App a1 a2 -> App <$> compile a1 <*> compile a2
-            Fmap f a -> Fmap f <$> compile a
-            Rep f b a -> Rep f b <$> compile a
-
-
-threadId :: Thread s a -> ThreadId
-threadId Accept {} = 0
-threadId Thread { threadId_ = i } = i
-
-
-run :: StateQueue st (Thread s r)
-    -> StateQueue st (Thread s r)
-    -> [s] -> ST st (Maybe r)
-run queue _ [] = fold f Nothing queue
-    where f a@Just{} _ _ = return a
-          f Nothing  _ x | Accept r <- x = return $ Just r
-                         | otherwise = return Nothing
-run queue newQueue (s:ss) = do
-    let accum q _ t =
-            case t of
-                Accept {} -> return q
-                Thread _ c ->
-                    foldM (\q x -> tryInsert x q) q $ c s
-    newQueue <- fold accum newQueue queue
-    let veryNewQueue = clear queue
-    run newQueue veryNewQueue ss
-
-tryInsert :: Thread s r -> StateQueue st (Thread s r) -> ST st (StateQueue st (Thread s r))
-tryInsert t@(threadId -> ThreadId i) queue = do
-    alreadyPresent <- member i queue
-    if alreadyPresent
-        then return queue
-        else insert i t queue
-
-match :: Regexp s a r -> [s] -> Maybe r
-match r s = runST $ do
-    let (rr, ThreadId numStates) = renumber r
-    q1 <- empty numStates
-    q2 <- empty numStates
-    let threads = compile rr (\x -> [Accept x])
-    q1 <- foldM (\q t -> tryInsert t q) q1 threads
-    run q1 q2 s
-
--- This turns out to be much faster than the standard foldM,
--- because of inlining.
-foldM :: Monad m => (a -> b -> m a) -> a -> [b] -> m a
-foldM f a l = foldr (\x k a -> f a x >>= k) return l $ a
diff --git a/Text/Regex/Applicative/Interface.hs b/Text/Regex/Applicative/Interface.hs
--- a/Text/Regex/Applicative/Interface.hs
+++ b/Text/Regex/Applicative/Interface.hs
@@ -1,67 +1,44 @@
-{-# LANGUAGE Rank2Types, FlexibleInstances, TypeFamilies #-}
+{-# LANGUAGE Rank2Types, FlexibleInstances, TypeFamilies, TupleSections #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
 module Text.Regex.Applicative.Interface where
 import Control.Applicative hiding (empty)
 import qualified Control.Applicative
 import Data.Traversable
 import Data.String
-import Text.Regex.Applicative.Implementation
-
--- | Type of regular expressions that recognize symbols of type @s@ and
--- produce a result of type @a@.
---
--- Regular expressions can be built using 'Functor', 'Applicative' and
--- 'Alternative' instances in the following natural way:
---
--- * @f@ '<$>' @ra@ matches iff @ra@ matches, and its return value is the result
--- of applying @f@ to the return value of @ra@.
---
--- * 'pure' @x@ matches the empty string (i.e. it does not consume any symbols),
--- and its return value is @x@
---
--- * @rf@ '<*>' @ra@ matches a string iff it is a concatenation of two
--- strings: one matched by @rf@ and the other matched by @ra@. The return value
--- is @f a@, where @f@ and @a@ are the return values of @rf@ and @ra@
--- respectively.
---
--- * @ra@ '<|>' @rb@ matches a string which is accepted by either @ra@ or @rb@.
--- It is left-biased, so if both can match, the result of @ra@ is used.
---
--- * 'Control.Applicative.empty' is a regular expression which does not match any string.
---
--- * 'many' @ra@ matches concatenation of zero or more strings matched by @ra@
--- and returns the list of @ra@'s return values on those strings.
-newtype RE s a = RE (forall i . Regexp s i a)
+import Data.Maybe
+import Text.Regex.Applicative.Types
+import Text.Regex.Applicative.Object
 
 instance Functor (RE s) where
-    fmap f (RE x) = RE $ Fmap f x
+    fmap f x = Fmap f x
 
 instance Applicative (RE s) where
-    pure x = const x <$> RE Eps
-    (RE a1) <*> (RE a2) = RE $ App a1 a2
+    pure x = const x <$> Eps
+    a1 <*> a2 = App a1 a2
 
 instance Alternative (RE s) where
-    (RE a1) <|> (RE a2) = RE $ Alt a1 a2
-    empty = RE Eps
-    many (RE a) = reverse <$> RE (Rep (flip (:)) [] a)
+    a1 <|> a2 = Alt a1 a2
+    empty = Eps
+    many a = reverse <$> Rep Greedy (flip (:)) [] a
 
 instance (char ~ Char, string ~ String) => IsString (RE char string) where
     fromString = string
 
--- | Matches and returns a single symbol which satisfies the predicate
+-- | Match and return a single symbol which satisfies the predicate
 psym :: (s -> Bool) -> RE s s
-psym p = RE $ Symbol (error "Not numbered symbol") p
+psym p = Symbol (error "Not numbered symbol") p
 
--- | Matches and returns the given symbol
+-- | Match and return the given symbol
 sym :: Eq s => s -> RE s s
 sym s = psym (s ==)
 
--- | Matches and returns any single symbol
+-- | Match and return any single symbol
 anySym :: RE s s
 anySym = psym (const True)
 
--- | Matches and returns the given sequence of symbols.
+-- | Match and return the given sequence of symbols.
 --
--- Note that you there is an 'IsString' instance for regular expression, so
+-- Note that there is an 'IsString' instance for regular expression, so
 -- if you enable the @OverloadedStrings@ language extension, you can write
 -- @string \"foo\"@ simply as @\"foo\"@.
 --
@@ -76,12 +53,122 @@
 string :: Eq a => [a] -> RE a [a]
 string = traverse sym
 
--- | Greedily matches zero or more symbols, which are combined using the given
--- folding function
-reFoldl :: (b -> a -> b) -> b -> RE s a -> RE s b
-reFoldl f b (RE a) = RE $ Rep f b a
+-- | Match zero or more instances of the given expression, which are combined using
+-- the given folding function.
+--
+-- 'Greediness' argument controls whether this regular expression should match
+-- as many as possible ('Greedy') or as few as possible ('NonGreedy') instances
+-- of the underlying expression.
+reFoldl :: Greediness -> (b -> a -> b) -> b -> RE s a -> RE s b
+reFoldl g f b a = Rep g f b a
 
--- | Attempts to match a string of symbols against the regular expression
+-- | Match zero or more instances of the given expression, but as
+-- few of them as possible (i.e. /non-greedily/). A greedy equivalent of 'few'
+-- is 'many'.
+--
+-- Examples:
+--
+-- >Text.Regex.Applicative> findFirstPrefix (few anySym  <* "b") "ababab"
+-- >Just ("a","abab")
+-- >Text.Regex.Applicative> findFirstPrefix (many anySym  <* "b") "ababab"
+-- >Just ("ababa","")
+few :: RE s a -> RE s [a]
+few a = reverse <$> Rep NonGreedy (flip (:)) [] a
+
+-- | @s =~ a = match a s@
 (=~) :: [s] -> RE s a -> Maybe a
-s =~ (RE a) = match a s
+s =~ a = match a s
 infix 2 =~
+
+-- | Attempt to match a string of symbols against the regular expression.
+-- Note that the whole string (not just some part of it) should be matched.
+--
+-- Examples:
+--
+-- >Text.Regex.Applicative> match (sym 'a' <|> sym 'b') "a"
+-- >Just 'a'
+-- >Text.Regex.Applicative> match (sym 'a' <|> sym 'b') "ab"
+-- >Nothing
+--
+match :: RE s a -> [s] -> Maybe a
+match re str =
+    listToMaybe $
+    results $
+    foldl (flip step) (compile re) str
+
+-- | Find a string prefix which is matched by the regular expression.
+--
+-- Of all matching prefixes, pick one using left bias (prefer the left part of
+-- '<|>' to the right part) and greediness.
+--
+-- This is the match which a backtracking engine (such as Perl's one) would find
+-- first.
+--
+-- If match is found, the rest of the input is also returned.
+--
+-- Examples:
+--
+-- >Text.Regex.Applicative> findFirstPrefix ("a" <|> "ab") "abc"
+-- >Just ("a","bc")
+-- >Text.Regex.Applicative> findFirstPrefix ("ab" <|> "a") "abc"
+-- >Just ("ab","c")
+-- >Text.Regex.Applicative> findFirstPrefix "bc" "abc"
+-- >Nothing
+findFirstPrefix :: RE s a -> [s] -> Maybe (a, [s])
+findFirstPrefix re str = go (compile re) str Nothing
+    where
+    walk obj [] = (obj, Nothing)
+    walk obj (t:ts) =
+        case getResult t of
+            Just r -> (obj, Just r)
+            Nothing -> walk (addThread t obj) ts
+
+    go obj str resOld =
+        case walk emptyObject $ threads obj of
+            (obj', resThis) ->
+                let res = ((,str) <$> resThis) <|> resOld
+                in
+                    case str of
+                        [] -> res
+                        _ | failed obj' -> res
+                        (s:ss) -> go (step s obj') ss res
+
+-- | Find the longest string prefix which is matched by the regular expression.
+--
+-- Submatches are still determined using left bias and greediness, so this is
+-- different from POSIX semantics.
+--
+-- If match is found, the rest of the input is also returned.
+--
+-- Examples:
+--
+-- >Text.Regex.Applicative Data.Char> let keyword = "if"
+-- >Text.Regex.Applicative Data.Char> let identifier = many $ psym isAlpha
+-- >Text.Regex.Applicative Data.Char> let lexeme = (Left <$> keyword) <|> (Right <$> identifier)
+-- >Text.Regex.Applicative Data.Char> findLongestPrefix lexeme "if foo"
+-- >Just (Left "if"," foo")
+-- >Text.Regex.Applicative Data.Char> findLongestPrefix lexeme "iffoo"
+-- >Just (Right "iffoo","")
+findLongestPrefix :: RE s a -> [s] -> Maybe (a, [s])
+findLongestPrefix re str = go (compile re) str Nothing
+    where
+    go obj str resOld =
+        let res = (fmap (,str) $ listToMaybe $ results obj) <|> resOld
+        in
+            case str of
+                [] -> res
+                _ | failed obj -> res
+                (s:ss) -> go (step s obj) ss res
+
+-- | Find the shortest prefix (analogous to 'findLongestPrefix')
+findShortestPrefix :: RE s a -> [s] -> Maybe (a, [s])
+findShortestPrefix re str = go (compile re) str
+    where
+    go obj str =
+        case results obj of
+            r : _ -> Just (r, str)
+            [] ->
+                case str of
+                    [] -> Nothing
+                    _ | failed obj -> Nothing
+                    s:ss -> go (step s obj) ss
diff --git a/Text/Regex/Applicative/Object.hs b/Text/Regex/Applicative/Object.hs
new file mode 100644
--- /dev/null
+++ b/Text/Regex/Applicative/Object.hs
@@ -0,0 +1,134 @@
+--------------------------------------------------------------------
+-- |
+-- Module    : Text.Regex.Applicative.Object
+-- Copyright : (c) Roman Cheplyaka
+-- License   : MIT
+--
+-- Maintainer: Roman Cheplyaka <roma@ro-che.info>
+-- Stability : experimental
+--
+-- This is a low-level interface to the regex engine.
+--------------------------------------------------------------------
+{-# LANGUAGE TypeFamilies, GADTs #-}
+module Text.Regex.Applicative.Object
+    ( ReObject
+    , compile
+    , emptyObject
+    , Thread
+    , threads
+    , failed
+    , isResult
+    , getResult
+    , results
+    , ThreadId
+    , threadId
+    , step
+    , stepThread
+    , fromThreads
+    , addThread
+    ) where
+
+import Text.Regex.Applicative.Types
+import qualified Text.Regex.Applicative.StateQueue as SQ
+import qualified Text.Regex.Applicative.Compile as Compile
+import Data.Maybe
+import Control.Monad.State
+import Control.Applicative hiding (empty)
+
+-- | The state of the engine is represented as a \"regex object\" of type
+-- @'ReObject' s r@, where @s@ is the type of symbols and @r@ is the
+-- result type (as in the 'RE' type). Think of 'ReObject' as a collection of
+-- 'Thread's ordered by priority. E.g. threads generated by the left part of
+-- '<|>' come before the threads generated by the right part.
+newtype ReObject s r = ReObject (SQ.StateQueue (Thread s r))
+
+-- | List of all threads of an object. Each non-result thread has a unique id.
+threads :: ReObject s r -> [Thread s r]
+threads (ReObject sq) = SQ.getElements sq
+
+-- | Create an object from a list of threads. It is recommended that all
+-- threads come from the same 'ReObject', unless you know what you're doing.
+-- However, it should be safe to filter out or rearrange threads.
+fromThreads :: [Thread s r] -> ReObject s r
+fromThreads ts = foldl (flip addThread) emptyObject ts
+
+-- | Check whether a thread is a result thread
+isResult :: Thread s r -> Bool
+isResult Accept {} = True
+isResult _ = False
+
+-- | Return the result of a result thread, or 'Nothing' if it's not a result
+-- thread
+getResult :: Thread s r -> Maybe r
+getResult (Accept r) = Just r
+getResult _ = Nothing
+
+-- | Check if the object has no threads. In that case it never will
+-- produce any new threads as a result of 'step'.
+failed :: ReObject s r -> Bool
+failed obj = null $ threads obj
+
+-- | Empty object (with no threads)
+emptyObject :: ReObject s r
+emptyObject = ReObject $ SQ.empty
+
+-- | Extract the result values from all the result threads of an object
+results :: ReObject s r -> [r]
+results obj =
+    mapMaybe getResult $ threads obj
+
+-- | Feed a symbol into a regex object
+step :: s -> ReObject s r -> ReObject s r
+step s (ReObject sq) =
+    let accum q t =
+            case t of
+                Accept {} -> q
+                Thread _ c ->
+                    foldl (\q x -> addThread x q) q $ c s
+        newQueue = SQ.fold accum emptyObject sq
+    in newQueue
+
+-- | Feed a symbol into a non-result thread. It is an error to call 'stepThread'
+-- on a result thread.
+stepThread :: s -> Thread s r -> [Thread s r]
+stepThread s t =
+    case t of
+        Thread _ c -> c s
+        Accept {} -> error "stepThread on a result"
+
+-- | Add a thread to an object. The new thread will have lower priority than the
+-- threads which are already in the object.
+--
+-- If a (non-result) thread with the same id already exists in the object, the
+-- object is not changed.
+addThread :: Thread s r -> ReObject s r -> ReObject s r
+addThread t (ReObject q) =
+    case t of
+        Accept {} -> ReObject $ SQ.insert t q
+        Thread { threadId_ = ThreadId i } -> ReObject $ SQ.insertUnique i t q
+
+-- | Compile a regular expression into a regular expression object
+compile :: RE s r -> ReObject s r
+compile =
+    fromThreads .
+    flip Compile.compile (\x -> [Accept x]) .
+    renumber
+
+renumber :: RE s a -> RE s a
+renumber e = flip evalState 1 $ go e
+  where
+    go :: RE s a -> State ThreadId (RE s a)
+    go e =
+        case e of
+            Eps -> return Eps
+            Symbol _ p -> Symbol <$> fresh <*> pure p
+            Alt a1 a2 -> Alt <$> go a1 <*> go a2
+            App a1 a2 -> App <$> go a1 <*> go a2
+            Fmap f a -> Fmap f <$> go a
+            Rep g f b a -> Rep g f b <$> go a
+
+fresh :: (MonadState m, StateType m ~ ThreadId) => m ThreadId
+fresh = do
+    i <- get
+    put $! i+1
+    return i
diff --git a/Text/Regex/Applicative/Reference.hs b/Text/Regex/Applicative/Reference.hs
deleted file mode 100644
--- a/Text/Regex/Applicative/Reference.hs
+++ /dev/null
@@ -1,73 +0,0 @@
---------------------------------------------------------------------
--- |
--- Module    : Text.Regex.Applicative.Reference
--- Copyright : (c) Roman Cheplyaka
--- License   : MIT
---
--- Maintainer: Roman Cheplyaka <roma@ro-che.info>
--- Stability : experimental
---
--- Reference implementation (using backtracking)
---------------------------------------------------------------------
-
-{-# LANGUAGE GADTs #-}
-module Text.Regex.Applicative.Reference (reference) where
-import Prelude hiding (getChar)
-import Text.Regex.Applicative.Implementation
-import Text.Regex.Applicative.Interface
-import Control.Applicative
-import Control.Monad
-
-
--- A simple parsing monad
-newtype P s a = P { unP :: [s] -> [(a, [s])] }
-
-instance Monad (P s) where
-    return x = P $ \s -> [(x, s)]
-    (P a) >>= k = P $ \s ->
-        a s >>= \(x,s) -> unP (k x) s
-
-instance Functor (P s) where
-    fmap = liftM
-
-instance Applicative (P s) where
-    (<*>) = ap
-    pure = return
-
-instance Alternative (P s) where
-    empty = P $ const []
-    P a1 <|> P a2 = P $ \s ->
-        a1 s ++ a2 s
-
-getChar :: P s s
-getChar = P $ \s ->
-    case s of
-        [] -> []
-        c:cs -> [(c,cs)]
-
-re2monad :: Regexp s r a -> P s a
-re2monad r =
-    case r of
-        Eps -> return $ error "eps"
-        Symbol _ p -> do
-            c <- getChar
-            if p c then return c else empty
-        Alt a1 a2 -> re2monad a1 <|> re2monad a2
-        App a1 a2 -> re2monad a1 <*> re2monad a2
-        Fmap f a -> fmap f $ re2monad a
-        Rep f b a -> rep b
-            where
-            am = re2monad a
-            rep b = (do a <- am; rep $ f b a) <|> return b
-
-runP :: P s a -> [s] -> Maybe a
-runP m s = case filter (null . snd) $ unP m s of
-    (r, _) : _ -> Just r
-    _ -> Nothing
-
--- | 'reference' @r@ @s@ should give the same results as @s@ '=~' @r@.
---
--- However, this is not very efficient implementation and is supposed to be
--- used for testing only.
-reference :: RE s a -> [s] -> Maybe a
-reference (RE r) s = runP (re2monad r) s
diff --git a/Text/Regex/Applicative/StateQueue.hs b/Text/Regex/Applicative/StateQueue.hs
--- a/Text/Regex/Applicative/StateQueue.hs
+++ b/Text/Regex/Applicative/StateQueue.hs
@@ -3,63 +3,49 @@
     ( StateQueue
     , empty
     , insert
-    , member
+    , insertUnique
     , fold
-    , clear
+    , getElements
     ) where
 
 import Prelude hiding (read, lookup, replicate)
-import Data.Vector.Mutable hiding (clear)
-import Control.Monad
-import Control.Monad.ST
+import qualified Data.IntSet as IntSet
 
-data IndexedValue a = IndexedValue
-    { ixKey :: !Int
-    , _ixValue :: !a
+data StateQueue a = StateQueue
+    { elements :: [a]
+    , ids :: IntSet.IntSet
     }
 
-data StateQueue s a = StateQueue
-    { dense :: !(MVector s (IndexedValue a))
-    , sparseToDense :: !(MVector s Int)
-    , size :: !Int
-    }
+getElements :: StateQueue a -> [a]
+getElements = reverse . elements
 
 {-# INLINE empty #-}
-empty :: Int -> ST st (StateQueue st a)
-empty maxSize = do
-    d <- replicate maxSize (IndexedValue 0 $ error "SQ: Uninitialized value")
-    s2d <- replicate maxSize 0
-    return StateQueue
-        { dense = d
-        , sparseToDense = s2d
-        , size = 0
-        }
+empty :: StateQueue a
+empty = StateQueue
+    { elements = []
+    , ids = IntSet.empty
+    }
 
 {-# INLINE insert #-}
-insert
-    :: Int -> a -> StateQueue st a
-    -> ST st (StateQueue st a)
-insert i v sq@StateQueue { size = size } = do
-    write (sparseToDense sq) i size
-    write (dense sq) size (IndexedValue i v)
-    return $ sq { size = size + 1 }
+insertUnique
+    :: Int
+    -> a
+    -> StateQueue a
+    -> StateQueue a
+insertUnique i v sq@StateQueue {..} =
+    if i `IntSet.member` ids
+        then sq
+        else sq { elements = v : elements
+                , ids = IntSet.insert i ids
+                }
 
-{-# INLINE member #-}
-member
-    :: Int -> StateQueue st a -> ST st Bool
-member i StateQueue {..} = {-# SCC "member" #-} do
-    di <- read sparseToDense i
-    if (di >= size) then return False else do
-    IndexedValue { ixKey = dvKey } <- read dense di
-    return $ dvKey == i
+insert
+    :: a
+    -> StateQueue a
+    -> StateQueue a
+insert v sq =
+    sq { elements = v : elements sq }
 
 {-# INLINE fold #-}
-fold :: (a -> Int -> x -> ST st a) -> a -> StateQueue st x -> ST st a
-fold f acc0 sq = foldM step acc0 [0 .. size sq - 1]
-  where
-    step acc n = do
-        IndexedValue i v <- read (dense sq) n
-        f acc i v
-
-{-# INLINE clear #-}
-clear sq = sq { size = 0 }
+fold :: (a -> x -> a) -> a -> StateQueue x -> a
+fold f acc0 sq = foldl f acc0 (reverse $ elements sq)
diff --git a/Text/Regex/Applicative/Types.hs b/Text/Regex/Applicative/Types.hs
--- a/Text/Regex/Applicative/Types.hs
+++ b/Text/Regex/Applicative/Types.hs
@@ -3,24 +3,59 @@
 module Text.Regex.Applicative.Types where
 
 newtype ThreadId = ThreadId Int
-    deriving (Show, Eq, Ord, Num)
+    deriving (Show, Eq, Ord, Num, Real, Enum, Integral)
 
-data Thread s a
+-- | A thread either is a result or corresponds to a symbol in the regular
+-- expression, which is expected by that thread.
+data Thread s r
     = Thread
         { threadId_ :: ThreadId
-        , _threadCont :: s -> [Thread s a]
+        , _threadCont :: s -> [Thread s r]
         }
-    | Accept a
+    | Accept r
 
-data Regexp s i a where
-    Eps :: Regexp s i a
-    Symbol :: i -> (s -> Bool) -> Regexp s i s
-    Alt :: Regexp s i a -> Regexp s i a -> Regexp s i a
-    App :: Regexp s i (a -> b) -> Regexp s i a -> Regexp s i b
-    Fmap :: (a -> b) -> Regexp s i a -> Regexp s i b
-    Rep :: (b -> a -> b) -- folding function (like in foldl)
+-- | Returns thread identifier. This will be 'Just' for ordinary threads and
+-- 'Nothing' for results.
+threadId :: Thread s r -> Maybe ThreadId
+threadId Thread { threadId_ = i } = Just i
+threadId _ = Nothing
+
+data Greediness = Greedy | NonGreedy
+    deriving (Show, Read, Eq, Ord, Enum)
+
+-- | Type of regular expressions that recognize symbols of type @s@ and
+-- produce a result of type @a@.
+--
+-- Regular expressions can be built using 'Functor', 'Applicative' and
+-- 'Alternative' instances in the following natural way:
+--
+-- * @f@ '<$>' @ra@ matches iff @ra@ matches, and its return value is the result
+-- of applying @f@ to the return value of @ra@.
+--
+-- * 'pure' @x@ matches the empty string (i.e. it does not consume any symbols),
+-- and its return value is @x@
+--
+-- * @rf@ '<*>' @ra@ matches a string iff it is a concatenation of two
+-- strings: one matched by @rf@ and the other matched by @ra@. The return value
+-- is @f a@, where @f@ and @a@ are the return values of @rf@ and @ra@
+-- respectively.
+--
+-- * @ra@ '<|>' @rb@ matches a string which is accepted by either @ra@ or @rb@.
+-- It is left-biased, so if both can match, the result of @ra@ is used.
+--
+-- * 'Control.Applicative.empty' is a regular expression which does not match any string.
+--
+-- * 'many' @ra@ matches concatenation of zero or more strings matched by @ra@
+-- and returns the list of @ra@'s return values on those strings.
+data RE s a where
+    Eps :: RE s a
+    Symbol :: ThreadId -> (s -> Bool) -> RE s s
+    Alt :: RE s a -> RE s a -> RE s a
+    App :: RE s (a -> b) -> RE s a -> RE s b
+    Fmap :: (a -> b) -> RE s a -> RE s b
+    Rep :: Greediness    -- repetition may be greedy or not
+        -> (b -> a -> b) -- folding function (like in foldl)
         -> b             -- the value for zero matches, and also the initial value
                          -- for the folding function
-        -> Regexp s i a
-        -> Regexp s i b
-
+        -> RE s a
+        -> RE s b
diff --git a/regex-applicative.cabal b/regex-applicative.cabal
--- a/regex-applicative.cabal
+++ b/regex-applicative.cabal
@@ -9,7 +9,7 @@
 -- standards guiding when and how versions should be incremented.
 
 -- DO NOT FORGET TO UPDATE THE GIT TAG BELOW!!!
-Version:             0.1.4
+Version:             0.1.5
 
 -- A short (one-line) description of the package.
 Synopsis:            Regex-based parsing with applicative interface
@@ -56,23 +56,21 @@
 Source-repository this
   type:     git
   location: git://github.com/feuerbach/regex-applicative.git
-  tag:      v0.1.4
+  tag:      v0.1.5
 
 Library
   -- Packages needed in order to build this package.
-  Build-depends:       base >= 4.2 && < 4.4,
+  Build-depends:       base >= 4.2 && < 4.5,
                        containers >= 0.3 && < 0.5,
-                       monads-tf == 0.1.*,
-                       vector == 0.7.*
+                       monads-tf == 0.1.*
 
 
   -- Modules exported by the library.
   Exposed-modules:     Text.Regex.Applicative
-                       Text.Regex.Applicative.Reference
+                       Text.Regex.Applicative.Object
   
   -- Modules not exported by this package.
   Other-modules:       Text.Regex.Applicative.Interface
-                       Text.Regex.Applicative.Implementation
                        Text.Regex.Applicative.Types
                        Text.Regex.Applicative.Compile
                        Text.Regex.Applicative.StateQueue
