diff --git a/lib/Data/Prednote/Expressions.hs b/lib/Data/Prednote/Expressions.hs
--- a/lib/Data/Prednote/Expressions.hs
+++ b/lib/Data/Prednote/Expressions.hs
@@ -19,7 +19,6 @@
 import qualified Data.Prednote.Expressions.Infix as I
 import qualified Data.Prednote.Expressions.RPN as R
 import qualified Data.Prednote.Pdct as P
-import qualified Control.Monad.Exception.Synchronous as Ex
 
 -- | A single type for both RPN tokens and infix tokens.
 newtype Token a = Token { unToken :: I.InfixToken a }
@@ -71,13 +70,13 @@
 parseExpression
   :: ExprDesc
   -> [Token a]
-  -> Ex.Exceptional Error (P.Pdct a)
+  -> Either Error (P.Pdct a)
 parseExpression e toks = do
   rpnToks <- case e of
-    Infix -> Ex.fromMaybe "unbalanced parentheses\n"
+    Infix -> maybe (Left "unbalanced parentheses\n") Right
              . I.createRPN
              . map unToken
              $ toks
-    RPN -> Ex.fromMaybe "parentheses in an RPN expression\n"
+    RPN -> maybe (Left "parentheses in an RPN expression\n") Right
            $ toksToRPN toks
   R.parseRPN rpnToks
diff --git a/lib/Data/Prednote/Expressions/RPN.hs b/lib/Data/Prednote/Expressions/RPN.hs
--- a/lib/Data/Prednote/Expressions/RPN.hs
+++ b/lib/Data/Prednote/Expressions/RPN.hs
@@ -6,7 +6,6 @@
 -- where @and@ and @or@ are binary and @not@ is unary.
 module Data.Prednote.Expressions.RPN where
 
-import qualified Control.Monad.Exception.Synchronous as Ex
 import qualified Data.Foldable as Fdbl
 import qualified Data.Prednote.Pdct as P
 import Data.Prednote.Pdct ((&&&), (|||))
@@ -33,17 +32,17 @@
 pushOperator
   :: Operator
   -> [P.Pdct a]
-  -> Ex.Exceptional Error [P.Pdct a]
+  -> Either Error [P.Pdct a]
 pushOperator o ts = case o of
   OpAnd -> case ts of
     x:y:zs -> return $ (y &&& x) : zs
-    _ -> Ex.throw $ err "and"
+    _ -> Left $ err "and"
   OpOr -> case ts of
     x:y:zs -> return $ (y ||| x) : zs
-    _ -> Ex.throw $ err "or"
+    _ -> Left $ err "or"
   OpNot -> case ts of
     x:zs -> return $ P.not x : zs
-    _ -> Ex.throw $ err "not"
+    _ -> Left $ err "not"
   where
     err x = "insufficient operands to apply \"" <> x
             <> "\" operator\n"
@@ -51,7 +50,7 @@
 pushToken
   :: [P.Pdct a]
   -> RPNToken a
-  -> Ex.Exceptional Error [P.Pdct a]
+  -> Either Error [P.Pdct a]
 pushToken ts t = case t of
   TokOperand p -> return $ pushOperand p ts
   TokOperator o -> pushOperator o ts
@@ -64,13 +63,13 @@
 parseRPN
   :: Fdbl.Foldable f
   => f (RPNToken a)
-  -> Ex.Exceptional Error (P.Pdct a)
+  -> Either Error (P.Pdct a)
 parseRPN ts = do
   trees <- Fdbl.foldlM pushToken [] ts
   case trees of
-    [] -> Ex.throw $ "bad expression: no operands left on the stack\n"
+    [] -> Left $ "bad expression: no operands left on the stack\n"
     x:[] -> return x
-    xs -> Ex.throw
+    xs -> Left
       $ "bad expression: multiple operands left on the stack:\n"
       <> ( X.concat
            . map C._text
diff --git a/prednote.cabal b/prednote.cabal
--- a/prednote.cabal
+++ b/prednote.cabal
@@ -1,5 +1,5 @@
 name:                prednote
-version:             0.14.0.0
+version:             0.16.0.0
 synopsis:            Build and evaluate trees of predicates
 description:
   Build and evaluate trees of predicates. For example, you might build
@@ -35,8 +35,7 @@
     , Data.Prednote.Test
 
   build-depends:
-      base >= 4.6 && < 5
-    , explicit-exception ==0.1.*
+      base == 4.6.*
     , rainbow ==0.4.*
     , split ==0.2.*
     , text == 0.11.*
@@ -53,7 +52,10 @@
   -- build-dependencies in any build, even non-test builds.
   if flag(test)
     build-depends:
-        QuickCheck ==2.6.*
+        base ==4.6.*
+      , QuickCheck ==2.6.*
+      , rainbow ==0.4.*
+      , text ==0.11.*
   else
     buildable: False
 
