diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## Parser combinators 1.1.0
+
+* Added support for ternary operators; see `TernR` in
+    `Control.Monad.Combinators.Expr`.
+
 ## Parser combinators 1.0.3
 
 * Dropped support for GHC 7.10.
diff --git a/Control/Monad/Combinators/Expr.hs b/Control/Monad/Combinators/Expr.hs
--- a/Control/Monad/Combinators/Expr.hs
+++ b/Control/Monad/Combinators/Expr.hs
@@ -30,6 +30,18 @@
   | InfixR  (m (a -> a -> a)) -- ^ Right-associative infix
   | Prefix  (m (a -> a))      -- ^ Prefix
   | Postfix (m (a -> a))      -- ^ Postfix
+  | TernR   (m (m (a -> a -> a -> a)))
+    -- ^ Right-associative ternary. Right-associative means that
+    -- @a ? b : d ? e : f@ parsed as
+    -- @a ? b : (d ? e : f)@ and not as @(a ? b : d) ? e : f@.
+    --
+    -- The outer monadic action parses the first separator (e.g. @?@) and
+    -- returns an action (of type @m (a -> a -> a -> a)@) that parses the
+    -- second separator (e.g. @:@).
+    --
+    -- Example usage:
+    --
+    -- >>> TernR ((If <$ char ':') <$ char '?')
 
 -- | @'makeExprParser' term table@ builds an expression parser for terms
 -- @term@ with operators from @table@, taking the associativity and
@@ -89,13 +101,14 @@
 
 addPrecLevel :: MonadPlus m => m a -> [Operator m a] -> m a
 addPrecLevel term ops =
-  term' >>= \x -> choice [ras' x, las' x, nas' x, return x]
+  term' >>= \x -> choice [ras' x, las' x, nas' x, tern' x, return x]
   where
-    (ras, las, nas, prefix, postfix) = foldr splitOp ([],[],[],[],[]) ops
+    (ras, las, nas, prefix, postfix, tern) = foldr splitOp ([],[],[],[],[],[]) ops
     term' = pTerm (choice prefix) term (choice postfix)
     ras'  = pInfixR (choice ras) term'
     las'  = pInfixL (choice las) term'
     nas'  = pInfixN (choice nas) term'
+    tern' = pTernR  (choice tern) term'
 {-# INLINEABLE addPrecLevel #-}
 
 -- | @pTerm prefix term postfix@ parses a @term@ surrounded by optional
@@ -144,19 +157,33 @@
   return $ f x y
 {-# INLINE pInfixR #-}
 
+-- | Parse the first separator of a ternary operator
+
+pTernR :: MonadPlus m => m (m (a -> a -> a -> a)) -> m a -> a -> m a
+pTernR sep1 p x = do
+  sep2 <- sep1
+  y <- p >>= \r -> pTernR sep1 p r `mplus` return r
+  f <- sep2
+  z <- p >>= \r -> pTernR sep1 p r `mplus` return r
+  return $ f x y z
+{-# INLINE pTernR #-}
+
 type Batch m a =
   ( [m (a -> a -> a)]
   , [m (a -> a -> a)]
   , [m (a -> a -> a)]
   , [m (a -> a)]
-  , [m (a -> a)] )
+  , [m (a -> a)]
+  , [m (m (a -> a -> a -> a))]
+  )
 
 -- | A helper to separate various operators (binary, unary, and according to
 -- associativity) and return them in a tuple.
 
 splitOp :: Operator m a -> Batch m a -> Batch m a
-splitOp (InfixR  op) (r, l, n, pre, post) = (op:r, l, n, pre, post)
-splitOp (InfixL  op) (r, l, n, pre, post) = (r, op:l, n, pre, post)
-splitOp (InfixN  op) (r, l, n, pre, post) = (r, l, op:n, pre, post)
-splitOp (Prefix  op) (r, l, n, pre, post) = (r, l, n, op:pre, post)
-splitOp (Postfix op) (r, l, n, pre, post) = (r, l, n, pre, op:post)
+splitOp (InfixR  op) (r, l, n, pre, post, tern) = (op:r, l, n, pre, post, tern)
+splitOp (InfixL  op) (r, l, n, pre, post, tern) = (r, op:l, n, pre, post, tern)
+splitOp (InfixN  op) (r, l, n, pre, post, tern) = (r, l, op:n, pre, post, tern)
+splitOp (Prefix  op) (r, l, n, pre, post, tern) = (r, l, n, op:pre, post, tern)
+splitOp (Postfix op) (r, l, n, pre, post, tern) = (r, l, n, pre, op:post, tern)
+splitOp (TernR   op) (r, l, n, pre, post, tern) = (r, l, n, pre, post, op:tern)
diff --git a/parser-combinators.cabal b/parser-combinators.cabal
--- a/parser-combinators.cabal
+++ b/parser-combinators.cabal
@@ -1,5 +1,5 @@
 name:                 parser-combinators
-version:              1.0.3
+version:              1.1.0
 cabal-version:        1.18
 tested-with:          GHC==8.0.2, GHC==8.2.2, GHC==8.4.4, GHC==8.6.5
 license:              BSD3
