diff --git a/Test.hs b/Test.hs
--- a/Test.hs
+++ b/Test.hs
@@ -29,7 +29,7 @@
   >> envTest
   >> envOptTest
   >> envOptDefTest
-
+  >> eitherSwitchTest
 rawProg :: ProgramT Raw IO Bool
 rawProg = raw (pure True)
 
@@ -128,3 +128,24 @@
   testMaybeBool =<< fmap not <$> test (envOptDefProg "POP" (== ("POOP" :: String))) (State mempty mempty mempty)
   setEnv "CORPUS" "POOP"
   testMaybeBool =<< test (envOptDefProg "POP" (== ("POOP" :: String))) (State mempty mempty mempty)
+
+eitherSwitchProg :: (x -> Bool) -> (y -> Bool) -> ProgramT (Arg "xy" (Either x y) & Raw) IO (Either Bool Bool)
+eitherSwitchProg xpred ypred = arg \case { Left x -> raw (pure (Left $ xpred x)); Right y -> raw (pure (Right $ ypred y)) }
+
+eitherSwitchTest  :: IO ()
+eitherSwitchTest = do
+  let example = eitherSwitchProg (== (10 :: Int)) (== ("Hello" :: String))
+  let ploof a c = runCommanderT (run example) (State a mempty mempty) >>= c
+  ploof ["10"] \case
+    Just (Left True) -> pure ()
+    _ -> exitFailure
+  ploof ["Hello"] \case
+    Just (Right True) -> pure ()
+    _ -> exitFailure
+  ploof ["Poop"] \case
+    Just (Right False) -> pure ()
+    _ -> exitFailure
+  ploof [] \case
+    Nothing -> pure ()
+    _ -> exitFailure
+
diff --git a/commander-cli.cabal b/commander-cli.cabal
--- a/commander-cli.cabal
+++ b/commander-cli.cabal
@@ -1,7 +1,7 @@
 cabal-version:       2.4
 
 name:                commander-cli
-version:             0.6.2.0
+version:             0.7.0.0
 synopsis:            A command line argument/option parser library built around a monadic metaphor
 description:         A command line argument/option parser library built around a monadic metaphor.
 homepage:            https://github.com/SamuelSchlesinger/commander-cli
@@ -15,7 +15,7 @@
 extra-source-files:  CHANGELOG.md, README.md
 
 library
-  exposed-modules:     Options.Commander
+  exposed-modules:     Options.Commander, Control.Monad.Commander
   other-extensions:    ViewPatterns,
                        DerivingVia,
                        StandaloneDeriving,
diff --git a/src/Control/Monad/Commander.hs b/src/Control/Monad/Commander.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Commander.hs
@@ -0,0 +1,141 @@
+{-# LANGUAGE DeriveFunctor #-}
+{- |
+Module: Control.Monad.Commander
+Description: A monad for stateful, backtracking computations
+Copyright: (c) Samuel Schlesinger 2020
+License: MIT
+Maintainer: sgschlesinger@gmail.com
+Stability: experimental
+Portability: POSIX, Windows
+-}
+module Control.Monad.Commander (
+  -- ** The CommanderT Monad
+  {- |
+    The 'CommanderT' monad is how your CLI programs are interpreted by 'run'.
+    It has the ability to backtrack and it maintains some state.
+  -}
+  CommanderT(Action, Defeat, Victory), runCommanderT,
+) where
+
+import Control.Monad (ap)
+import Control.Monad.Trans (MonadTrans, lift, liftIO, MonadIO)
+import Control.Applicative (Alternative(empty, (<|>)))
+
+-- | A 'CommanderT' action is a metaphor for a military commander. At each
+-- step, we have a new 'Action' to take, or we could have experienced
+-- 'Defeat', or we can see 'Victory'. While a real life commander
+-- worries about moving his troops around in order to achieve a victory in
+-- battle, a 'CommanderT' worries about iteratively transforming a state 
+-- to find some value. We will deal with the subset of these actions where
+-- every function must decrease the size of the state, as those are the
+-- actions for which this is a monad.
+data CommanderT state m a
+  = Action (state -> m (CommanderT state m a, state))
+  | Defeat
+  | Victory a
+  deriving Functor
+
+-- | We can run a 'CommanderT' action on a state and see if it has
+-- a successful campaign.
+runCommanderT :: Monad m 
+              => CommanderT state m a 
+              -> state 
+              -> m (Maybe a)
+runCommanderT (Action action) state = do
+  (action', state') <- action state
+  m <- runCommanderT action' state'
+  return m
+runCommanderT Defeat _ = return Nothing
+runCommanderT (Victory a) _ = return (Just a)
+
+instance (Monad m) => Applicative (CommanderT state m) where
+  (<*>) = ap
+  pure = Victory
+
+instance MonadTrans (CommanderT state) where
+  lift ma = Action $ \state -> do
+    a <- ma
+    return (pure a, state)
+
+instance MonadIO m => MonadIO (CommanderT state m) where
+  liftIO ma = Action $ \state -> do
+    a <- liftIO ma
+    return (pure a, state)
+
+-- Return laws:
+-- Goal: return a >>= k = k a
+-- Proof: return a >>= k 
+--      = Victory a >>= k 
+--      = k a 
+--      = k a
+-- Goal: m >>= return = m
+-- Proof:
+--   Case 1: Defeat >>= return = Defeat
+--   Case 2: Victory a >>= return 
+--         = Victory a
+--   Case 3: Action action >>= return
+--         = Action $ \state -> do
+--             (action', state') <- action state
+--             return (action' >>= return, state')
+--
+-- Case 3 serves as an inductive proof only if action' is a strictly smaller action
+-- than action!
+--
+--  Bind laws:
+--  Goal: m >>= (\x -> k x >>= h) = (m >>= k) >>= h
+--  Proof: 
+--    Case 1: Defeat >>= _ = Defeat
+--    Case 2: Victory a >>= (\x -> k x >>= f)
+--          = k a >>= f
+--          = (Victory a >>= k) >>= f
+--    Case 3: Action action >>= (\x -> k x >>= h)
+--          = Action $ \state -> do
+--              (action', state') <- action state
+--              return (action' >>= (\x -> k x >>= h), state')
+--          = Action $ \state -> do
+--              (action', state') <- action state
+--              return ((action' >>= k) >>= h, state') -- by IH
+--    On the other hand,
+--            (Action action >>= k) >>= h
+--          = Action (\state -> do
+--              (action', state') <- action state
+--              return (action' >>= k, state') >>= h
+--          = Action $ \state -> do
+--              (action', state') <- action state
+--              return ((action' >>= k) >>= h, state')
+--               
+--   This completes our proof for the case when these are finite.
+--   Basically, we require that the stream an action produces is strictly
+--   smaller than any other streams, for all state inputs. The ways that we
+--   use this monad transformer satisify this constraint. If this
+--   constraint is not met, many of our functions will return bottom.
+--
+--   We can certainly have functions that operate on these things and
+--   change them safely, without violating this constraint. All of the
+--   functions that we define on CommanderT programs preserve this
+--   property.
+--
+--   An example of a violating term might be:
+--
+--   violator :: CommanderT state m
+--   violator = Action (\state -> return (violator, state))
+--
+--   The principled way to include this type would be to parameterize it by
+--   a natural number and have that natural number decrease over time, but
+--   to enforce that in Haskell we couldn't have the monad instance
+--   anyways. This is the way to go for now, despite the type violating the
+--   monad laws potentially for infinite inputs. 
+instance Monad m => Monad (CommanderT state m) where
+  Defeat >>= _ = Defeat
+  Victory a >>= f = f a
+  Action action >>= f = Action $ \state -> do
+    (action', state') <- action state
+    return (action' >>= f, state')
+
+instance Monad m => Alternative (CommanderT state m) where
+  empty = Defeat 
+  Defeat <|> a = a 
+  v@(Victory _) <|> _ = v
+  Action action <|> p = Action $ \state -> do
+    (action', state') <- action state 
+    return (action' <|> p, state')
diff --git a/src/Options/Commander.hs b/src/Options/Commander.hs
--- a/src/Options/Commander.hs
+++ b/src/Options/Commander.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE UndecidableInstances #-}
 {-# LANGUAGE BlockArguments #-}
 {-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE DeriveGeneric #-}
@@ -14,7 +15,6 @@
 {-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE TypeApplications #-}
 {-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE DeriveFunctor #-}
 {-# LANGUAGE AllowAmbiguousTypes #-}
 {-# LANGUAGE PolyKinds #-}
 {-# LANGUAGE GADTs #-}
@@ -146,6 +146,7 @@
 import qualified Data.ByteString as SBS
 import qualified Data.ByteString.Char8 as BS8
 import qualified Data.ByteString.Lazy as LBS
+import Control.Monad.Commander
 
 -- | A class for interpreting command line arguments into Haskell types.
 class Typeable t => Unrender t where
@@ -170,17 +171,10 @@
 instance Unrender () where
   unrender = unrenderSmall
 
-instance Unrender a => Unrender (Maybe a) where
-  unrender x = justCase x <|> nothingCase x where
-    justCase x' = do
-      x'' <- stripPrefix "Just " x'
-      return (unrender x'')
-    nothingCase x' = if x' == "Nothing" then return Nothing else Nothing
-
 instance (Unrender a, Unrender b) => Unrender (Either a b) where
   unrender x = leftCase x <|> rightCase x where
-    leftCase  = fmap Left  . unrender <=< stripPrefix "Left "
-    rightCase = fmap Right . unrender <=< stripPrefix "Right "
+    leftCase  = fmap Left  . unrender
+    rightCase = fmap Right . unrender
 
 instance Unrender Bool where
   unrender = unrenderSmall
@@ -258,125 +252,6 @@
 -- options or arguments fails, runs the second, otherwise failing.
 data a + b
 infixr 2 +
-
--- | A 'CommanderT' action is a metaphor for a military commander. At each
--- step, we have a new 'Action' to take, or we could have experienced
--- 'Defeat', or we can see 'Victory'. While a real life commander
--- worries about moving his troops around in order to achieve a victory in
--- battle, a 'CommanderT' worries about iteratively transforming a state 
--- to find some value. We will deal with the subset of these actions where
--- every function must decrease the size of the state, as those are the
--- actions for which this is a monad.
-data CommanderT state m a
-  = Action (state -> m (CommanderT state m a, state))
-  | Defeat
-  | Victory a
-  deriving Functor
-
--- | We can run a 'CommanderT' action on a state and see if it has
--- a successful campaign.
-runCommanderT :: Monad m 
-              => CommanderT state m a 
-              -> state 
-              -> m (Maybe a)
-runCommanderT (Action action) state = do
-  (action', state') <- action state
-  m <- runCommanderT action' state'
-  return m
-runCommanderT Defeat _ = return Nothing
-runCommanderT (Victory a) _ = return (Just a)
-
-instance (Monad m) => Applicative (CommanderT state m) where
-  (<*>) = ap
-  pure = Victory
-
-instance MonadTrans (CommanderT state) where
-  lift ma = Action $ \state -> do
-    a <- ma
-    return (pure a, state)
-
-instance MonadIO m => MonadIO (CommanderT state m) where
-  liftIO ma = Action $ \state -> do
-    a <- liftIO ma
-    return (pure a, state)
-
--- Return laws:
--- Goal: return a >>= k = k a
--- Proof: return a >>= k 
---      = Victory a >>= k 
---      = k a 
---      = k a
--- Goal: m >>= return = m
--- Proof:
---   Case 1: Defeat >>= return = Defeat
---   Case 2: Victory a >>= return 
---         = Victory a
---   Case 3: Action action >>= return
---         = Action $ \state -> do
---             (action', state') <- action state
---             return (action' >>= return, state')
---
--- Case 3 serves as an inductive proof only if action' is a strictly smaller action
--- than action!
---
---  Bind laws:
---  Goal: m >>= (\x -> k x >>= h) = (m >>= k) >>= h
---  Proof: 
---    Case 1: Defeat >>= _ = Defeat
---    Case 2: Victory a >>= (\x -> k x >>= f)
---          = k a >>= f
---          = (Victory a >>= k) >>= f
---    Case 3: Action action >>= (\x -> k x >>= h)
---          = Action $ \state -> do
---              (action', state') <- action state
---              return (action' >>= (\x -> k x >>= h), state')
---          = Action $ \state -> do
---              (action', state') <- action state
---              return ((action' >>= k) >>= h, state') -- by IH
---    On the other hand,
---            (Action action >>= k) >>= h
---          = Action (\state -> do
---              (action', state') <- action state
---              return (action' >>= k, state') >>= h
---          = Action $ \state -> do
---              (action', state') <- action state
---              return ((action' >>= k) >>= h, state')
---               
---   This completes our proof for the case when these are finite.
---   Basically, we require that the stream an action produces is strictly
---   smaller than any other streams, for all state inputs. The ways that we
---   use this monad transformer satisify this constraint. If this
---   constraint is not met, many of our functions will return bottom.
---
---   We can certainly have functions that operate on these things and
---   change them safely, without violating this constraint. All of the
---   functions that we define on CommanderT programs preserve this
---   property.
---
---   An example of a violating term might be:
---
---   violator :: CommanderT state m
---   violator = Action (\state -> return (violator, state))
---
---   The principled way to include this type would be to parameterize it by
---   a natural number and have that natural number decrease over time, but
---   to enforce that in Haskell we couldn't have the monad instance
---   anyways. This is the way to go for now, despite the type violating the
---   monad laws potentially for infinite inputs. 
-instance Monad m => Monad (CommanderT state m) where
-  Defeat >>= _ = Defeat
-  Victory a >>= f = f a
-  Action action >>= f = Action $ \state -> do
-    (action', state') <- action state
-    return (action' >>= f, state')
-
-instance Monad m => Alternative (CommanderT state m) where
-  empty = Defeat 
-  Defeat <|> a = a 
-  v@(Victory _) <|> _ = v
-  Action action <|> p = Action $ \state -> do
-    (action', state') <- action state 
-    return (action' <|> p, state')
 
 -- | This is the 'State' that the 'CommanderT' library uses for its role in
 -- this library. It is not inlined, because that does nothing but obfuscate
