diff --git a/JustParse.cabal b/JustParse.cabal
--- a/JustParse.cabal
+++ b/JustParse.cabal
@@ -1,5 +1,5 @@
 name:                JustParse
-version:             2.0
+version:             2.1
 synopsis:            A simple and comprehensive Haskell parsing library
 description:         A simple and comprehensive Haskell parsing library
 homepage:            https://github.com/grantslatton/JustParse
@@ -25,4 +25,4 @@
         base >= 4.2 && < 5
     hs-source-dirs: src
     extensions: MultiParamTypeClasses, Rank2Types, FlexibleInstances, FlexibleContexts, Safe, TupleSections, UndecidableInstances
-    ghc-options: -O2 -Wall
+    ghc-options: -O2 
diff --git a/src/Data/JustParse.hs b/src/Data/JustParse.hs
--- a/src/Data/JustParse.hs
+++ b/src/Data/JustParse.hs
@@ -8,7 +8,7 @@
 Portability : portable
 -} 
 
---{-# LANGUAGE Safe #-}
+{-# LANGUAGE Safe #-}
 module Data.JustParse (
     -- * Overview
     -- $overview
diff --git a/src/Data/JustParse/Char.hs b/src/Data/JustParse/Char.hs
--- a/src/Data/JustParse/Char.hs
+++ b/src/Data/JustParse/Char.hs
@@ -10,7 +10,7 @@
 Several useful parsers for dealing with 'String's.
 -}
 
---{-# LANGUAGE Safe #-}
+{-# LANGUAGE Safe #-}
 module Data.JustParse.Char (
     char,
     anyChar,
@@ -40,74 +40,92 @@
 -- | Parse a specic char.
 char :: Stream s Char => Char -> Parser s Char
 char = token
+{-# INLINE char #-}
 
 -- | Parse any char.
 anyChar :: Stream s Char =>  Parser s Char
 anyChar = anyToken
+{-# INLINE anyChar #-}
 
 -- | Parse a specific char, ignoring case.
 caseInsensitiveChar :: Stream s Char => Char -> Parser s Char
 caseInsensitiveChar c = char (toUpper c) <|> char (toLower c)
+{-# INLINE caseInsensitiveChar #-}
 
 -- | Parse any char that is ASCII.
 ascii :: Stream s Char =>  Parser s Char
 ascii = satisfy isAscii
+{-# INLINE ascii #-}
 
 -- | Parse any char that is Latin-1.
 latin1 :: Stream s Char =>  Parser s Char
 latin1 = satisfy isLatin1
+{-# INLINE latin1 #-}
 
 -- | Parse a control character.
 control :: Stream s Char =>  Parser s Char
 control = satisfy isControl
+{-# INLINE control #-}
 
 -- | Parse a space.
 space :: Stream s Char =>  Parser s Char
 space = satisfy isSpace
+{-# INLINE space #-}
 
 -- | Parse a lowercase character.
 lower :: Stream s Char =>  Parser s Char
 lower = satisfy isLower
+{-# INLINE lower #-}
 
 -- | Parse an uppercase character.
 upper :: Stream s Char =>  Parser s Char
 upper = satisfy isUpper
+{-# INLINE upper #-}
 
 -- | Parse an alphabetic character.
 alpha :: Stream s Char =>  Parser s Char
 alpha = satisfy isAlpha
+{-# INLINE alpha #-}
 
 -- | Parse an alphanumeric character.
 alphaNum :: Stream s Char =>  Parser s Char
 alphaNum = satisfy isAlphaNum
+{-# INLINE alphaNum #-}
 
 -- | Parse a printable (non-control) character.
 print :: Stream s Char =>  Parser s Char
 print = satisfy isPrint
+{-# INLINE print #-}
 
 -- | Parse a digit.
 digit :: Stream s Char =>  Parser s Char
 digit = satisfy isDigit
+{-# INLINE digit #-}
 
 -- | Parse an octal digit.
 octDigit :: Stream s Char =>  Parser s Char
 octDigit = satisfy isOctDigit
+{-# INLINE octDigit #-}
 
 -- | Parse a hexadeciaml digit.
 hexDigit :: Stream s Char =>  Parser s Char
 hexDigit = satisfy isHexDigit
+{-# INLINE hexDigit #-}
 
 -- | Parse a specific string.
 string :: Stream s Char => String -> Parser s String
 string = mapM char 
+{-# INLINE string #-}
 
 -- | Parse a specfic string, ignoring case.
 caseInsensitiveString :: Stream s Char => String -> Parser s String
 caseInsensitiveString = mapM caseInsensitiveChar 
+{-# INLINE caseInsensitiveString #-}
 
 -- | Parses until a newline, carriage return + newline, or newline + carriage return.
 eol :: Stream s Char => Parser s String
 eol = choice [string "\r\n", string "\n\r", string "\n"]
+{-# INLINE eol #-}
 
 -- | Makes common types such as 'String's into a Stream.
 instance Eq t => Stream [t] t where
diff --git a/src/Data/JustParse/Combinator.hs b/src/Data/JustParse/Combinator.hs
--- a/src/Data/JustParse/Combinator.hs
+++ b/src/Data/JustParse/Combinator.hs
@@ -10,8 +10,7 @@
 The bread and butter of combinatory parsing.
 -}
 
---{-# LANGUAGE Safe #-}
---{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE Safe #-}
 module Data.JustParse.Combinator (
     -- * Utility Parsers
     assert,
@@ -24,6 +23,7 @@
     option,
     optional,
     test,
+    try,
     (<|>),
 
     -- * Token Parsers
@@ -44,6 +44,7 @@
     exactly,
     many,
     many1,
+    manyTill,
     mN,
     sepBy,
     sepBy1,
@@ -52,6 +53,7 @@
     sepEndBy,
     sepEndBy1,
     takeWhile,
+    takeWhile1,
 
     -- * Group Parsers
     choice,
@@ -82,7 +84,8 @@
     sepEndBy1_,
     skipMany_,
     skipMany1_,
-    takeWhile_
+    takeWhile_,
+    takeWhile1_
 ) where
 
 import Prelude hiding ( print, length, takeWhile )
@@ -104,58 +107,82 @@
         Just s' -> case uncons s' of
             Nothing -> [Partial $ parse (satisfy f)]
             Just (x, xs) -> [Done x (Just xs) | f x]
+{-# INLINE satisfy #-}
 
 -- | A parser that succeeds on 'True' and fails on 'False'. 
 guard :: Stream s t => Bool -> Parser s ()
 guard = M.guard
+{-# INLINE guard #-}
 
 -- | Synonym of 'guard'.
 assert :: Stream s t => Bool -> Parser s ()
 assert = guard
+{-# INLINE assert #-}
 
 -- | Only succeeds when supplied with 'Nothing'.
 eof :: Stream s t => Parser s ()
 eof = notFollowedBy anyToken
+{-# INLINE eof #-}
 
 -- | Parse a token that is a member of the list of tokens.
 oneOf :: (Eq t, Stream s t) => [t] -> Parser s t
 oneOf ts = satisfy (`elem` ts)
+{-# INLINE oneOf #-}
 
 -- | Parse a token that is not a member of the list of tokens.
 noneOf :: (Eq t, Stream s t) => [t] -> Parser s t
 noneOf ts = satisfy (`notElem` ts)
+{-# INLINE noneOf #-}
 
 -- | Parse a specific token.
 token :: (Eq t, Stream s t) => t -> Parser s t
 token t = satisfy (==t)
+{-# INLINE token #-}
 
 -- | Parse any token.
 anyToken :: Stream s t => Parser s t
 anyToken = satisfy (const True)
+{-# INLINE anyToken #-}
 
 -- | Parse tokens while a predicate remains true.
 takeWhile :: Stream s t => (t -> Bool) -> Parser s [t]
 takeWhile = many . satisfy
+{-# INLINE takeWhile #-}
 
+-- | Parse one or more tokens while a predicate remains true.
+takeWhile1 :: Stream s t => (t -> Bool) -> Parser s [t]
+takeWhile1 = many1 . satisfy
+{-# INLINE takeWhile1 #-}
+
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
 takeWhile_ :: Stream s t => (t -> Bool) -> Parser s [t]
 takeWhile_ = many_ . satisfy
+{-# INLINE takeWhile_ #-}
 
+-- | Branches every iteration where one branch stops and one branch 
+-- continues.
+takeWhile1_ :: Stream s t => (t -> Bool) -> Parser s [t]
+takeWhile1_ = many1_ . satisfy
+{-# INLINE takeWhile1_ #-}
+
 -- | Splits the current parse branch between the two parsers.
 branch :: Parser s a -> Parser s a -> Parser s a
 branch a b = Parser $ \s -> parse a s ++ parse b s
+{-# INLINE branch #-}
 
 infixr 1 <||>
 -- | Infix version of 'branch'.
 (<||>) :: Parser s a -> Parser s a -> Parser s a
 (<||>) = branch
+{-# INLINE (<||>) #-}
 
 -- | @mN m n p@ parses between @m@ and @n@ occurences of @p@, inclusive.
 mN :: Stream s t => Int -> Int -> Parser s a -> Parser s [a]
 mN _ 0 _ = Parser $ \s -> [Done [] s]
 mN 0 n p = M.liftM2 (:) p (mN 0 (n-1) p) A.<|> return []
 mN m n p = M.liftM2 (:) p (mN (m-1) (n-1) p)
+{-# INLINE mN #-}
 
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
@@ -163,46 +190,56 @@
 mN_ _ 0 _ = Parser $ \s -> [Done [] s]
 mN_ 0 n p = M.liftM2 (:) p (mN 0 (n-1) p) <||> return []
 mN_ m n p = M.liftM2 (:) p (mN (m-1) (n-1) p)
+{-# INLINE mN_ #-}
 
 -- | Synonym of 'count'.
 exactly :: Stream s t => Int -> Parser s a -> Parser s [a]
 exactly n = mN n n
+{-# INLINE exactly #-}
 
 -- | Applies a parser at least @n@ times.
 atLeast :: Stream s t => Int -> Parser s a -> Parser s [a]
 atLeast n = mN n (-1)
+{-# INLINE atLeast #-}
 
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
 atLeast_ :: Stream s t => Int -> Parser s a -> Parser s [a]
 atLeast_ n = mN_ n (-1)
+{-# INLINE atLeast_ #-}
 
 -- | Applies a parser at most @n@ times.
 atMost :: Stream s t => Int -> Parser s a -> Parser s [a]
 atMost  = mN 0
+{-# INLINE atMost #-}
 
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
 atMost_ :: Stream s t => Int -> Parser s a -> Parser s [a]
 atMost_ = mN 0
+{-# INLINE atMost_ #-}
 
 -- | Applies a parser zero or more times.
 many :: Stream s t => Parser s a -> Parser s [a]
 many = A.many
+{-# INLINE many #-}
 
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
 many_ :: Parser s a -> Parser s [a]
 many_ p = return [] <||> M.liftM2 (:) p (many_ p)
+{-# INLINE many_ #-}
 
 -- | Applies a parser one or more times.
 many1 :: Stream s t => Parser s a -> Parser s [a]
 many1 p = M.liftM2 (:) p (many p)
+{-# INLINE many1 #-}
 
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
 many1_ :: Parser s a -> Parser s [a]
 many1_ p = M.liftM2 (:) p (many_ p)
+{-# INLINE many1_ #-}
 
 -- | Return 'True' if the parser would succeed if one were to apply it,
 -- otherwise, it returns 'False'. It does not consume input.
@@ -213,31 +250,37 @@
         case a of
             Nothing -> return False
             _ -> return True
+{-# INLINE test #-}
 
 infixr 1 <|>
 -- | @a \<|\> b@ is equivalent to @'choice' [a,b]@. That is, first @a@ is
 -- tried, and if it yields no results, @b@ is tried.
 (<|>) :: Stream s t => Parser s a -> Parser s a -> Parser s a
 (<|>) = (A.<|>)
+{-# INLINE (<|>) #-}
 
 -- | Attempt to apply each parser in the list in order until one succeeds.
 choice :: Stream s t => [Parser s a] -> Parser s a
 choice = foldl1' (A.<|>) 
+{-# INLINE choice #-}
 
 -- | Given a list of parsers, split off a branch for each one.
 choice_ :: Stream s t => [Parser s a] -> Parser s a
 choice_ = foldl1' (<||>)
+{-# INLINE choice_ #-}
 
 -- | Like 'choice', but returns the index of the successful parser as well
 -- as the result.
 select :: Stream s t => [Parser s a] -> Parser s (Int, a)
 select [] = M.mzero
 select (p:ps) = M.liftM (0,) p <|> M.liftM (\(x,y) -> (x+1,y)) (select ps)
+{-# INLINE select #-}
 
 -- | Like 'choice_', but returns the index of the successful parser.
 select_ :: Stream s t => [Parser s a] -> Parser s (Int, a)
 select_ [] = M.mzero
 select_ (p:ps) = M.liftM (0,) p <||> M.liftM (\(x,y) -> (x+1,y)) (select_ ps)
+{-# INLINE select_ #-}
 
 -- | Modifies a parser so that it will ony return the most consumptive
 -- succesful results. 
@@ -250,6 +293,7 @@
         g xs 
             | all isDone xs = [minimumBy (comparing (f . leftover)) xs]
             | otherwise = [Partial $ \s -> g $ extend s xs] 
+{-# INLINE greedy #-}
 
 -- | Attempts to apply a parser and returns a default value if it fails.
 option :: Stream s t => a -> Parser s a -> Parser s a
@@ -259,39 +303,47 @@
         case r of
             Nothing -> return v
             Just v' -> return v'
+{-# INLINE option #-}
 
 -- | Splits off two branches, one where the parse is attempted, and one 
 -- where it is not.
 option_ :: Stream s t => a -> Parser s a -> Parser s a
 option_ v p = option v p <||> return v
+{-# INLINE option_ #-}
 
 -- | Attempts to apply the parser, returning 'Nothing' upon failure, or
 -- the result wrapped in a 'Just'.
 optional :: Stream s t => Parser s a -> Parser s (Maybe a)
 optional = A.optional
+{-# INLINE optional #-}
 
 -- | Splits off two branches, one where the parse is attempted, and one 
 -- where it is not.
 optional_ :: Stream s t => Parser s a -> Parser s (Maybe a)
 optional_ p = M.liftM Just p <||> return Nothing
+{-# INLINE optional_ #-}
 
 -- | @sepBy1 p s@ parses many  occurences of @p@ separated by @s@.
 sepBy :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
 sepBy p s = sepBy1 p s A.<|> return []
+{-# INLINE sepBy #-}
 
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
 sepBy_ :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
 sepBy_ p s = sepBy1_ p s <||> return []
+{-# INLINE sepBy_ #-}
 
 -- | @sepBy1 p s@ parses one or more occurences of @p@ separated by @s@.
 sepBy1 :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
 sepBy1 p s = M.liftM2 (:) p (many (s >> p))
+{-# INLINE sepBy1 #-}
 
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
 sepBy1_ :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
 sepBy1_ p s = M.liftM2 (:) p (many_ (s >> p))
+{-# INLINE sepBy1_ #-}
 
 -- | Applies the parser and returns its result, but resets
 -- the 'Stream' as if it consumed nothing.
@@ -305,79 +357,95 @@
                 _ -> parse (lookAhead v) (streamAppend s s')
     in
         map g (p s)
+{-# INLINE lookAhead #-}
 
 -- | @count n p@ parses exactly @n@ occurences of @p@.
 count :: Stream s t => Int -> Parser s a -> Parser s [a]
 count = exactly
+{-# INLINE count #-}
 
 -- | Identical to 'many' except the result is discarded.
 skipMany :: Stream s t => Parser s a -> Parser s ()
 skipMany = M.void . many
+{-# INLINE skipMany #-}
 
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
 skipMany_ :: Stream s t => Parser s a -> Parser s ()
 skipMany_ = M.void . many_
+{-# INLINE skipMany_ #-}
 
 -- | Identical to 'many1' except the result is discarded.
 skipMany1 :: Stream s t => Parser s a -> Parser s ()
 skipMany1 = M.void . many1
+{-# INLINE skipMany1 #-}
 
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
 skipMany1_ :: Stream s t => Parser s a -> Parser s ()
 skipMany1_ = M.void . many1_
+{-# INLINE skipMany1_ #-}
 
 -- | @endBy p s@ parses multiple occurences of @p@ separated and ended by
 -- @s@.
 endBy :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
 endBy p s = many (p A.<* s)
+{-# INLINE endBy #-}
 
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
 endBy_ :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
 endBy_ p s = many_ (p A.<* s)
+{-# INLINE endBy_ #-}
 
 -- | @endBy1 p s@ parses one or more occurences of @p@ separated and ended 
 -- by @s@.
 endBy1 :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
 endBy1 p s = many1 (p A.<* s)
+{-# INLINE endBy1 #-}
 
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
 endBy1_ :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
 endBy1_ p s = many1_ (p A.<* s)
+{-# INLINE endBy1_ #-}
 
 -- | @sepEndBy p s@ parses multiple occurences of @p@ separated and 
 -- optionally ended by @s@.
 sepEndBy :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
 sepEndBy p s = sepBy p s A.<* optional s
+{-# INLINE sepEndBy #-}
 
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
 sepEndBy_ :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
 sepEndBy_ p s = sepBy_ p s A.<* optional s
+{-# INLINE sepEndBy_ #-}
 
 -- | @sepEndBy p s@ parses one or more occurences of @p@ separated and 
 -- optionally ended by @s@.
 sepEndBy1 :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
 sepEndBy1 p s = sepBy1 p s A.<* optional s
+{-# INLINE sepEndBy1 #-}
 
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
 sepEndBy1_ :: Stream s t => Parser s a -> Parser s b -> Parser s [a]
 sepEndBy1_ p s = sepBy1_ p s A.<* optional s
+{-# INLINE sepEndBy1_ #-}
 
 -- | @chainr p o x@ parses zero or more occurences of @p@ separated by @o@. 
 -- The result is the left associative application of the functions to the
 -- values. If @p@ succeeds zero times, @x@ is returned.
 chainl :: Stream s t => Parser s a -> Parser s (a -> a -> a) -> a -> Parser s a
 chainl p o x = chainl1 p o <|> return x
+{-# INLINE chainl #-}
 
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
 chainl_ :: Stream s t => Parser s a -> Parser s (a -> a -> a) -> a -> Parser s a
 chainl_ p o x = chainl1_ p o <||> return x
+{-# INLINE chainl_ #-}
 
 -- | Like 'chainl', but a minimum of one occurence of @p@ must be parsed.
 chainl1 :: Stream s t => Parser s a -> Parser s (a -> a -> a) -> Parser s a
@@ -389,6 +457,7 @@
                 y <- p
                 f (g x y)
             <|> return x
+{-# INLINE chainl1 #-}
 
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
@@ -401,15 +470,18 @@
                 y <- p
                 f (g x y)
             <||> return x
+{-# INLINE chainl1_ #-}
 
 -- | Like 'chainl', but right associative.
 chainr :: Stream s t => Parser s a -> Parser s (a -> a -> a) -> a -> Parser s a
 chainr p o x = chainr1 p o <|> return x
+{-# INLINE chainr #-}
 
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
 chainr_ :: Stream s t => Parser s a -> Parser s (a -> a -> a) -> a -> Parser s a
 chainr_ p o x = chainr1_ p o <||> return x
+{-# INLINE chainr_ #-}
 
 -- | Like 'chainl1', but right associative.
 chainr1 :: Stream s t => Parser s a -> Parser s (a -> a -> a) -> Parser s a
@@ -421,6 +493,7 @@
                 y <- chainr1 p o
                 return (g x y)
             <|> return x
+{-# INLINE chainr1 #-}
 
 -- | Branches every iteration where one branch stops and one branch 
 -- continues.
@@ -433,10 +506,12 @@
                 y <- chainr1_ p o
                 return (g x y)
             <||> return x
+{-# INLINE chainr1_ #-}
 
 -- | Only succeeds when the given parser fails. Consumes no input.
 notFollowedBy :: Stream s t => Parser s a -> Parser s ()
 notFollowedBy p = test p >>= assert . not
+{-# INLINE notFollowedBy #-}
 
 -- | @manyTill a b@ parses multiple occurences of @a@ until @b@ would 
 -- succeed if tried.
@@ -447,19 +522,23 @@
         if b 
             then return []
             else M.liftM2 (:) p (manyTill p e)
+{-# INLINE manyTill #-}
 
 -- | Does nothing -- only used for @Parsec@ compatability.
 try :: Stream s t => Parser s a -> Parser s a
 try = id
+{-# INLINE try #-}
 
 -- | @eitherP a b@ returns the result wrapped in a 'Left' if @a@ succeeds or
 -- a 'Right' if @b@ succeeds
 eitherP :: Stream s t => Parser s a -> Parser s b -> Parser s (Either a b)
 eitherP a b = M.liftM Left a <|> M.liftM Right b
+{-# INLINE eitherP #-}
 
 -- | Like 'eitherP', but tries both @a@ and @b@.
 eitherP_ :: Stream s t => Parser s a -> Parser s b -> Parser s (Either a b)
 eitherP_ a b = M.liftM Left a <||> M.liftM Right b
+{-# INLINE eitherP_ #-}
 
 -- | Parses a sequence of parsers in any order.
 perm :: Stream s t => [Parser s a] -> Parser s [a]
@@ -468,6 +547,7 @@
     do
         (i, r) <- select ps
         M.liftM (r:) (perm (let (a,b) = splitAt i ps in a ++ tail b)) 
+{-# INLINE perm #-}
 
 -- | Parses a sequence of parsers in all possible orders.
 perm_ :: Stream s t => [Parser s a] -> Parser s [a]
@@ -476,3 +556,4 @@
     do
         (i, r) <- select_ ps
         M.liftM (r:) (perm_ (let (a,b) = splitAt i ps in a ++ tail b)) 
+{-# INLINE perm_ #-}
diff --git a/src/Data/JustParse/Internal.hs b/src/Data/JustParse/Internal.hs
--- a/src/Data/JustParse/Internal.hs
+++ b/src/Data/JustParse/Internal.hs
@@ -14,7 +14,7 @@
 {-# LANGUAGE UndecidableInstances #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FunctionalDependencies #-}
---{-# LANGUAGE Safe #-}
+{-# LANGUAGE Safe #-}
 
 module Data.JustParse.Internal (
     Stream (..),
@@ -59,28 +59,38 @@
 
 instance Stream s t => Monoid (Parser s a) where
     mempty = mzero
+    {-# INLINE mempty #-}
     mappend = mplus
+    {-# INLINE mappend #-}
 
 instance Functor (Parser s) where
     fmap f (Parser p) = Parser $ map (fmap f) . p 
+    {-# INLINE fmap #-}
 
 instance Applicative (Parser s) where
     pure = return 
+    {-# INLINE pure #-}
     (<*>) = ap
+    {-# INLINE (<*>) #-}
 
 instance Stream s t => Alternative (Parser s) where
     empty = mzero
+    {-# INLINE empty #-}
     (<|>) = mplus
+    {-# INLINE (<|>) #-}
 
 instance Monad (Parser s) where
     return v = Parser $ \s -> [Done v s] 
+    {-# INLINE return #-}
     (Parser p) >>= f = Parser $ p >=> g
         where
             g (Done a s) = parse (f a) s 
             g (Partial p) = [Partial $ p >=> g] 
+    {-# INLINE (>>=) #-}
 
 instance Stream s t => MonadPlus (Parser s) where
     mzero = Parser $ const []
+    {-# INLINE mzero #-}
     mplus a b = Parser $ \s ->
         let
             g [] = parse b s
@@ -101,6 +111,7 @@
 
         in
             g (parse a s) 
+    {-# INLINE mplus #-}
 
 data Result s a 
     -- | A @Partial@ wraps the same function as a Parser. Supply it with 
@@ -121,28 +132,35 @@
 isDone :: Result s a -> Bool
 isDone (Done _ _) = True
 isDone _ = False
+{-# INLINE isDone #-}
 
 isPartial :: Result s a -> Bool
 isPartial (Partial _) = True
 isPartial _ = False
+{-# INLINE isPartial #-}
 
 -- | Lifts a parser into the result space
 toPartial :: Parser s a -> [Result s a]
 toPartial (Parser p) = [Partial p]
+{-# INLINE toPartial #-}
 
 instance Functor (Result s) where
     fmap f (Partial p) = Partial $ map (fmap f) . p
     fmap f (Done a s) = Done (f a) s
+    {-# INLINE fmap #-}
 
+
 instance Show a => Show (Result s a) where
     show (Partial _) = "Partial"
     show (Done a _) = show a
+    {-# INLINE show #-}
 
 -- | @finalize@ takes a list of results (presumably returned from a 
 -- 'Parser' or 'Partial', and supplies 'Nothing' to any remaining 'Partial' 
 -- values, so that only 'Done' values remain.
 finalize :: (Eq s, Monoid s) => [Result s a] -> [Result s a]
 finalize = extend Nothing
+{-# INLINE finalize #-}
 
 -- | @extend@ takes a @'Maybe' s@ as input, and supplies the input to all 
 -- values  in the 'Result' list. For 'Done' values, it appends 
@@ -153,8 +171,10 @@
     where
         g (Partial p) = p s
         g (Done a s') = [Done a (streamAppend s' s)]
+{-# INLINE extend #-}
 
 streamAppend :: (Eq s, Monoid s) => Maybe s -> Maybe s -> Maybe s
 streamAppend Nothing _ = Nothing 
 streamAppend (Just s) Nothing = if s == mempty then Nothing else Just s 
 streamAppend s s' = mappend s s'
+{-# INLINE streamAppend #-}
diff --git a/src/Data/JustParse/Language.hs b/src/Data/JustParse/Language.hs
--- a/src/Data/JustParse/Language.hs
+++ b/src/Data/JustParse/Language.hs
@@ -36,18 +36,22 @@
 -- The returned parser is greedy.
 regex :: Stream s Char => String -> Parser s Match
 regex = greedy . fromMaybe mzero . parseOnly regular
+{-# INLINE regex #-}
 
 -- | Like 'regex', but returns a branching (non-greedy) parser.
 regex_ :: Stream s Char => String -> Parser s Match
 regex_ = fromMaybe mzero . parseOnly regular
+{-# INLINE regex_ #-}
 
 -- | The same as 'regex', but only returns the full matched text.
 regex' :: Stream s Char => String -> Parser s String
 regex' = liftM matched . regex 
+{-# INLINE regex' #-}
 
 -- | The same as 'regex_', but only returns the full matched text.
 regex_' :: Stream s Char => String -> Parser s String
 regex_' = liftM matched . regex_
+{-# INLINE regex_' #-}
 
 
 -- | The result of a 'regex'
@@ -76,6 +80,7 @@
 
 regular :: (Stream s0 Char, Stream s1 Char) => Parser s0 (Parser s1 Match)
 regular = liftM (liftM mconcat . sequence) (many parser)
+{-# INLINE regular #-}
 
 parser :: (Stream s0 Char, Stream s1 Char) => Parser s0 (Parser s1 Match)
 parser = choice [
@@ -90,6 +95,7 @@
     negCharClass,
     period
     ]
+{-# INLINE parser #-}
 
 parserNP :: (Stream s0 Char, Stream s1 Char) => Parser s0 (Parser s1 Match)
 parserNP = choice [
@@ -103,6 +109,7 @@
     negCharClass,
     period
     ]
+{-# INLINE parserNP #-}
 
 
 
@@ -114,9 +121,11 @@
     group,
     period
     ]
+{-# INLINE restricted #-}
 
 unreserved :: Stream s Char => Parser s Char 
 unreserved = (char '\\' >> anyChar ) <|> noneOf "()[]\\*+{}^?|."
+{-# INLINE unreserved #-}
 
 character :: (Stream s0 Char, Stream s1 Char) => Parser s0 (Parser s1 Match)
 character = 
@@ -125,6 +134,7 @@
         return $ do
             c' <- char c
             return $ Match [c] []
+{-# INLINE character #-}
 
 charClass :: (Stream s0 Char, Stream s1 Char) => Parser s0 (Parser s1 Match)
 charClass = 
@@ -135,6 +145,7 @@
         return $ do
             c' <- oneOf c
             return $ Match [c'] []
+{-# INLINE charClass #-}
 
 negCharClass :: (Stream s0 Char, Stream s1 Char) => Parser s0 (Parser s1 Match)
 negCharClass = 
@@ -145,6 +156,7 @@
         return $ do
             c' <- noneOf c
             return $ Match [c'] []
+{-# INLINE negCharClass #-}
 
 period :: (Stream s0 Char, Stream s1 Char) => Parser s0 (Parser s1 Match)
 period = 
@@ -153,6 +165,7 @@
         return $ do
             c <- noneOf "\n\r"
             return $ Match [c] []
+{-# INLINE period #-}
 
 
 question :: (Stream s0 Char, Stream s1 Char) => Parser s0 (Parser s1 Match)
@@ -161,6 +174,7 @@
         p <- restricted
         char '?'
         return $ liftM mconcat (mN_ 0 1 p)
+{-# INLINE question #-}
 
 group :: (Stream s0 Char, Stream s1 Char) => Parser s0 (Parser s1 Match)
 group = 
@@ -171,6 +185,7 @@
         return $ do
             r <- p
             return $ r { groups = [r] } 
+{-# INLINE group #-}
 
 asterisk :: (Stream s0 Char, Stream s1 Char) => Parser s0 (Parser s1 Match)
 asterisk = 
@@ -178,6 +193,7 @@
         p <- restricted
         char '*'
         return $ liftM mconcat (many_ p)
+{-# INLINE asterisk #-}
 
 plus :: (Stream s0 Char, Stream s1 Char) => Parser s0 (Parser s1 Match)
 plus = 
@@ -185,6 +201,7 @@
         p <- restricted
         char '+'
         return $ liftM mconcat (many1_ p)
+{-# INLINE plus #-}
 
 mn :: (Stream s0 Char, Stream s1 Char) => Parser s0 (Parser s1 Match)
 mn = 
@@ -196,6 +213,7 @@
         r <- option (-1) decInt
         char '}'
         return $ liftM mconcat (mN_ l r p)
+{-# INLINE mn #-}
 
 pipe :: (Stream s0 Char, Stream s1 Char) => Parser s0 (Parser s1 Match)
 pipe = 
@@ -204,3 +222,4 @@
         char '|'
         p' <- parser
         return $ p <||> p'
+{-# INLINE pipe #-}
diff --git a/src/Data/JustParse/Numeric.hs b/src/Data/JustParse/Numeric.hs
--- a/src/Data/JustParse/Numeric.hs
+++ b/src/Data/JustParse/Numeric.hs
@@ -11,91 +11,147 @@
 -}
 
 module Data.JustParse.Numeric (
-    decFloat,
-    decFloat_,
+    decDigit,
+    hexDigit,
+    unsignedDecInt,
+    unsignedDecInt_,
+    unsignedHexInt,
+    unsignedHexInt_,
     decInt,
     decInt_,
     hexInt,
-    hexInt_
+    hexInt_,
+    decFloat,
+    decFloat_,
 ) where
 
---{-# LANGUAGE Safe #-}
+{-# LANGUAGE Safe #-}
 import Data.JustParse.Combinator
 import Data.JustParse.Internal
-import Data.JustParse.Char
+import qualified Data.JustParse.Char as C
 import Control.Monad ( liftM, liftM2 )
 import Data.Char ( ord, digitToInt, toUpper, isDigit, isHexDigit )
 
--- | Reads many decimal digits and returns them as an @Int@.
+-- | Parse a single decimal digit into an 'Int'.
+decDigit :: Stream s Char => Parser s Int
+decDigit = liftM digitToInt C.digit
+{-# INLINE decDigit #-}
+
+-- | Parse a single hexadecimal digit into an 'Int'.
+hexDigit :: Stream s Char => Parser s Int
+hexDigit = liftM digitToInt C.hexDigit
+{-# INLINE hexDigit #-}
+
+-- | Parse a series of decimal digits into an 'Int'.
+unsignedDecInt :: Stream s Char => Parser s Int
+unsignedDecInt = decDigit >>= g
+    where
+        g x = 
+            do
+                d <- decDigit
+                g (x*10+d)
+            <|> return x
+{-# INLINE unsignedDecInt #-}
+
+-- | Branching version of 'unsignedDecInt'.
+unsignedDecInt_ :: Stream s Char => Parser s Int
+unsignedDecInt_ = decDigit >>= g
+    where
+        g x = 
+            do
+                d <- decDigit
+                g (x*10+d)
+            <||> return x
+{-# INLINE unsignedDecInt_ #-}
+
+-- | Parse a series of hexadecimal digits into an 'Int'.
+unsignedHexInt :: Stream s Char => Parser s Int
+unsignedHexInt = hexDigit >>= g
+    where
+        g x = 
+            do
+                d <- hexDigit
+                g (x*16+d)
+            <|> return x
+{-# INLINE unsignedHexInt #-}
+
+-- | Branching version of 'unsignedHexInt'.
+unsignedHexInt_ :: Stream s Char => Parser s Int
+unsignedHexInt_ = hexDigit >>= g
+    where
+        g x = 
+            do
+                d <- hexDigit
+                g (x*16+d)
+            <||> return x
+{-# INLINE unsignedHexInt_ #-}
+
+-- | Parse a series of decimal digits into an 'Int' with an optional sign.
 decInt :: Stream s Char => Parser s Int
 decInt = 
     do
         sign <- optional (oneOf "-+")
-        num <- liftM read (many1 digit)
+        num <- unsignedDecInt
         case sign of
             Just '-' -> return (-num)
             _ -> return num
+{-# INLINE decInt #-}
 
--- | Branching version of decInt.
+-- | Branching version of 'decInt'.
 decInt_ :: Stream s Char => Parser s Int
 decInt_ = 
     do
         sign <- optional (oneOf "-+")
-        num <- liftM read (many1_ digit)
+        num <- unsignedDecInt_
         case sign of
             Just '-' -> return (-num)
             _ -> return num
+{-# INLINE decInt_ #-}
 
+-- | Parse a series of hexadecimal digits into an 'Int' with an optional 
+-- sign.
+hexInt :: Stream s Char => Parser s Int
+hexInt = 
+    do
+        sign <- optional (oneOf "-+")
+        num <- unsignedHexInt
+        case sign of
+            Just '-' -> return (-num)
+            _ -> return num
+{-# INLINE hexInt #-}
+
+-- | Branching versino of 'hexInt'.
+hexInt_ :: Stream s Char => Parser s Int
+hexInt_ = 
+    do
+        sign <- optional (oneOf "-+")
+        num <- unsignedHexInt_
+        case sign of
+            Just '-' -> return (-num)
+            _ -> return num
+{-# INLINE hexInt_ #-}
+
 -- | Parse a float. If a decimal point is present, it must have at 
 -- least one digit before and after the decimal point.
 decFloat :: Stream s Char => Parser s Float
 decFloat = 
     do
         sign <- optional (oneOf "-+")
-        whole <- many1 digit
-        fractional <- option ".0" (liftM2 (:) (char '.') (many1 digit))
+        whole <- many1 C.digit
+        fractional <- option ".0" (liftM2 (:) (C.char '.') (many1 C.digit))
         case sign of
             Just '-' -> return (-(read (whole ++ fractional)))
             _ -> return (read (whole ++ fractional))
+{-# INLINE decFloat #-}
 
 -- | Branching version of decFloat.
 decFloat_ :: Stream s Char => Parser s Float
 decFloat_ = 
     do
         sign <- optional (oneOf "-+")
-        whole <- many1_ digit
-        fractional <- option_ ".0" (liftM2 (:) (char '.') (many1_ digit))
+        whole <- many1_ C.digit
+        fractional <- option_ ".0" (liftM2 (:) (C.char '.') (many1_ C.digit))
         case sign of
             Just '-' -> return (-(read (whole ++ fractional)))
             _ -> return (read (whole ++ fractional))
-
-
--- | Reads many hexidecimal digits and returns them as an @Int@.
-hexInt :: Stream s Char => Parser s Int
-hexInt = 
-    do
-        sign <- optional (oneOf "-+")
-        num <- liftM (f . reverse) (many1 hexDigit)
-        case sign of
-            Just '-' -> return (-num)
-            _ -> return num
-    where
-        f [] = 0
-        f (x:xs) 
-            | isDigit x = digitToInt x + 16 * f xs 
-            | otherwise = ord (toUpper x) - ord 'A' + 16 * f xs
-
--- | Branching versino of 'hexInt'.
-hexInt_ :: Stream s Char => Parser s Int
-hexInt_ = 
-    do
-        sign <- optional (oneOf "-+")
-        num <- liftM (f . reverse) (many1_ hexDigit)
-        case sign of
-            Just '-' -> return (-num)
-            _ -> return num
-    where
-        f [] = 0
-        f (x:xs) 
-            | isDigit x = digitToInt x + 16 * f xs 
-            | otherwise = ord (toUpper x) - ord 'A' + 16 * f xs
+{-# INLINE decFloat_ #-}
