diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -16,16 +16,16 @@
 
 ```haskell
 file :: ProgramT File IO
-file = sub (arg \file -> arg \contents -> raw $ writeFile file contents) 
-   :+: sub (arg \file -> raw $ readFile file >>= putStrLn)
+file = sub (arg $ \file -> arg $ \contents -> raw $ writeFile file contents) 
+   :+: sub (arg $ \file -> raw $ readFile file >>= putStrLn)
 ```
 
 I can write a term of this type without specifying the File type by using the
 TypeApplications extension.
 
 ```haskell
-file = sub @"writer" (arg @"file" \file -> arg @"contents" \contents -> raw $ writeFile file contents)
-   :+: sub @"reader" (arg @"file" \file -> raw $ readFile file >>= putStrLn)
+file = sub @"writer" (arg @"file" $ \file -> arg @"contents" $ \contents -> raw $ writeFile file contents)
+   :+: sub @"reader" (arg @"file" $ \file -> raw $ readFile file >>= putStrLn)
 ```
 
 The library consists of a few basic types which are important for understanding
diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -20,16 +20,14 @@
 import Data.Either
 
 type TaskManager
-  = Named "task-manager" & ( 
-    "help" & Usage (Named "task-manager" & TaskManagerBasic)
-  + TaskManagerBasic)
-
-type TaskManagerBasic
-  = "edit"       & TaskProgram
+  = Named "task-manager" &
+  ( "help"       & Raw
+  + "edit"       & TaskProgram
   + "open"       & TaskProgram
   + "close"      & TaskProgram
   + "tasks"      & Raw
   + "priorities" & Raw
+  )
 
 type TaskProgram = Arg "task-name" String & Raw
   
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.2.0.1
+version:             0.3.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
@@ -17,6 +17,7 @@
 library
   exposed-modules:     Options.Commander
   other-extensions:    ViewPatterns,
+                       DerivingVia,
                        StandaloneDeriving,
                        GeneralizedNewtypeDeriving,
                        DerivingStrategies,
diff --git a/src/Options/Commander.hs b/src/Options/Commander.hs
--- a/src/Options/Commander.hs
+++ b/src/Options/Commander.hs
@@ -54,9 +54,9 @@
   -- ** Run CLI Programs
   command, command_,
   -- ** CLI Combinators
-  arg, opt, raw, sub, named, flag, toplevel, usage, (<+>),
+  arg, opt, raw, sub, named, flag, toplevel, (<+>), usage,
   -- ** Type Level CLI Description
-  type (&), type (+), Arg, Opt, Named, Usage, Raw, Flag,
+  type (&), type (+), Arg, Opt, Named, Raw, Flag,
   -- **
   HasProgram(run, hoist, invocations),
   ProgramT(ArgProgramT, unArgProgramT,
@@ -65,7 +65,6 @@
            SubProgramT, unSubProgramT,
            NamedProgramT, unNamedProgramT,
            FlagProgramT, unFlagProgramT,
-           UsageProgramT,
            (:+:)
            ),
   -- ** The CommanderT Monad
@@ -167,11 +166,6 @@
 -- sake of documentation.
 data Named :: Symbol -> *
 
--- | The type level usage combinator, taking a program type as an argument
--- and being interpreted as a program which prints out all of the
--- invocations of that particular program.
-data Usage :: * -> *
-
 -- | The type level program sequencing combinator, taking two program types
 -- and sequencing them one after another.
 data (&) :: k -> * -> *
@@ -363,15 +357,6 @@
   hoist n (RawProgramT m) = RawProgramT (n m)
   invocations = [mempty]
 
-instance HasProgram p => HasProgram (Usage p) where
-  data ProgramT (Usage p) m a = UsageProgramT
-  run _ = Action $ \s -> do
-    liftIO $ do
-      putStrLn "usage:"
-      void . traverse (putStrLn . unpack) $ invocations @p
-    return (Defeat, s)
-  hoist _ _ = UsageProgramT
-  invocations = [mempty]
 
 instance (KnownSymbol name, KnownSymbol option, HasProgram p, Unrender t) => HasProgram (Opt option name t & p) where
   newtype ProgramT (Opt option name t & p) m a = OptProgramT { unOptProgramT :: Maybe t -> ProgramT p m a }
@@ -483,9 +468,9 @@
 -- | A convenience combinator that constructs the program I often want
 -- to run out of a program I want to write.
 toplevel :: forall s p m a. (HasProgram p, KnownSymbol s, MonadIO m) 
-         => ProgramT p m a 
-         -> ProgramT (Named s & ("help" & Usage (Named s & p) + p)) m a
-toplevel p = named (sub usage :+: p) where
+         => ProgramT p m () 
+         -> ProgramT (Named s & ("help" & Raw + p)) m ()
+toplevel p = named (sub (usage @(Named s & (p + "help" & Raw))) <+> p)
 
 -- | The command line program which consists of trying to enter one and
 -- then trying the other.
@@ -496,5 +481,7 @@
 
 -- | A meta-combinator that takes a type-level description of a command 
 -- line program and produces a simple usage program.
-usage :: HasProgram p => ProgramT (Usage p) m a
-usage = UsageProgramT
+usage :: forall p m a. (MonadIO m, HasProgram p) => ProgramT Raw m ()
+usage = raw $ do
+  liftIO $ putStrLn "usage:"
+  void . traverse (liftIO . putStrLn . unpack) $ invocations @p
