diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,12 +1,24 @@
 Changelog
 =========
 
+Version 0.2.0.0
+---------------
+
+*February 26, 2020*
+
+<https://github.com/mstksg/typelits-printf/releases/tag/v0.2.0.0>
+
+*   Following <https://github.com/mstksg/typelits-printf/pull/3>, we can now
+    get "all three" benefits with `printf`.  This version removes all traces
+    of `pprintf`, `PP`, and `rprintf`, making `printf` the official
+    one-size-fits-all function. Thanks @kcsongor!
+
 Version 0.1.1.0
 ---------------
 
 *February 26, 2020*
 
-<https://github.com/mstksg/symbols-printf/releases/tag/v0.1.1.0>
+<https://github.com/mstksg/typelits-printf/releases/tag/v0.1.1.0>
 
 *   Major bug fix in parser (thanks @kcsongor)
 
@@ -15,6 +27,6 @@
 
 *February 25, 2020*
 
-<https://github.com/mstksg/symbols-printf/releases/tag/v0.1.0.0>
+<https://github.com/mstksg/typelits-printf/releases/tag/v0.1.0.0>
 
 *   Initial release
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -11,84 +11,63 @@
 
 An extensible and type-safe printf from parsing GHC TypeLits Symbol literals,
 matching the semantics of *[Text.Printf][]* in *base*.  The difference is that
-the variants here will always fail to compile if given arguments of the wrong
-type (or too many or too little arguments). Most of the variants also provide
-useful type feedback, telling you the type of arguments it expects and how many
+your `printf`s will always fail to compile if given arguments of the wrong type
+(or too many or too little arguments).  It also allows you to use types to help
+your development, by telling you the type of arguments it expects and how many
 when queried with `:t` or with typed holes.
 
 [Text.Printf]: https://hackage.haskell.org/package/base/docs/Text-Printf.html
 
-There are three main calling conventions offered:
-
 ```haskell
 ghci> putStrLn $ printf @"You have %.2f dollars, %s" 3.62 "Luigi"
 You have 3.62 dollars, Luigi
-
-ghci> putStrLn $ pprintf @"You have %.2f dollars, %s" (PP 3.62) (PP "Luigi")
-You have 3.62 dollars, Luigi
-
-ghci> putStrLn $ rprintf @"You have %.2f dollars, %s" (3.62 :% "Luigi" :% RNil)
-You have 3.62 dollars, Luigi
 ```
 
-Comparing their types:
+Looking at its type:
 
 ```haskell
-ghci> :t printf @"You have %.2f dollars, %s" 3.62 "Luigi"
-FormatFun '[ .... ] fun => fun
-
-ghci> :t pprintf @"You have %.2f dollars, %s" 3.62 "Luigi"
-PP "f" -> PP "s" -> String
-
-ghci> :t rprintf @"You have %.2f dollars, %s" 3.62 "Luigi"
-FormatArgs '["f", "s"] -> String
+ghci> :t printf @"You have %.2f dollars, %s"
+(FormatType "f" arg1, FormatType "s" arg2)
+  => arg1 -> arg2 -> String
 ```
 
-*   The type of `printf` doesn't tell you immediately what you
-    you need.  However, if you do try to use it, the type errors will guide you
-    along the way, iteratively.
-
-    ```haskell
-    ghci> printf @"You have %.2f dollars, %s"
-    -- ERROR: Call to printf missing argument fulfilling "%.2f"
-    -- Either provide an argument or rewrite the format string to not expect
-    -- one.
+It tells you that the result is an `arg1 -> arg2 -> String`: take two
+arguments, and return a `String`.  The first argument must be an instance of
+`FormatType "f"` (things that can be formatted by `%f`) and the second argument
+must be an instance of `FormatType "s"` (things that can be formatted by `%s`).
 
-    ghci> printf @"You have %.2f dollars, %s" 3.62
-    -- ERROR: Call to printf missing argument fulfilling "%s"
-    -- Either provide an argument or rewrite the format string to not expect
-    -- one.
+We can see this in action by progressively applying arguments:
 
-    ghci> printf @"You have %.2f dollars, %s" 3.62 "Luigi"
-    You have 3.62 dollars, Luigi
+```haskell
+ghci> :t printf @"You have %.2f dollars, %s" 3.62
+FormatType "s" arg1 => arg1 -> String
 
-    ghci> printf @"You have %.2f dollars, %s" 3.62 "Luigi" 72
-    -- ERROR: An extra argument of type Integer was given to a call to printf
-    -- Either remove the argument, or rewrite the format string to include the
-    -- appropriate hole.
-    ```
+ghci> :t printf @"You have %.2f dollars, %s" 3.62 "Luigi"
+String
+```
 
-*   For `pprintf`, it shows you need two arguments: A `PP "f"` (which is a
-    value that supports being formatted by `f`) like `PP 3.62`, and a `PP "s"`,
-    like `PP "Luigi"`.
+The type errors for forgetting to apply an argument (or applying too many
+arguments) are pretty clear:
 
-*   `rprintf` tells you you need a two-item hlist (from "Data.Vinyl.Core"),
-    where the first item implements `f` and the second item implements `s`:
-    `3.62 :% "Luigi" :% RNil` will do.
+```haskell
+ghci> putStrLn $ printf @"You have %.2f dollars, %s"
+-- ERROR: Call to printf missing argument fulfilling "%.2f"
+-- Either provide an argument or rewrite the format string to not expect
+-- one.
 
-The following table summarizes the features and drawbacks of each
-method:
+ghci> putStrLn $ printf @"You have %.2f dollars, %s" 3.62
+-- ERROR: Call to printf missing argument fulfilling "%s"
+-- Either provide an argument or rewrite the format string to not expect
+-- one.
 
-| Method    | True Polyarity   | Naked Arguments    | Type feedback        |
-| --------- | ---------------- | ------------------ | -------------------- |
-| `printf`  | Yes              | Yes                | Partial (via errors) |
-| `pprintf` | Yes              | No (requires `PP`) | Yes                  |
-| `rprintf` | No (HList-based) | Yes                | Yes                  |
+ghci> putStrLn $ printf @"You have %.2f dollars, %s" 3.62 "Luigi"
+You have 3.62 dollars, Luigi
 
-*Ideally* we would have a solution that has all three.  However, as of now, we
-have a "pick two" sort of situation.  Suggestions are definitely welcome,
-however, if you find something that satisfies all three benefits while still
-allowing for polymorphism!
+ghci> putStrLn $ printf @"You have %.2f dollars, %s" 3.62 "Luigi" 72
+-- ERROR: An extra argument of type Integer was given to a call to printf
+-- Either remove the argument, or rewrite the format string to include the
+-- appropriate hole.
+```
 
 You can extend functionality with formatting for your own types by providing
 instances of `FormatType`.
@@ -97,7 +76,7 @@
 
 For medium-length or long strings, the parsing can be fairly slow and cause
 slow compile times.  This might be due to the underlying mechanism that the
-*[symbols][]* package exploits.
+*[symbols][]* package exploits...or just GHC performance issues in general.
 
 [symbols]: https://hackage.haskell.org/package/symbols
 
diff --git a/src/GHC/TypeLits/Printf.hs b/src/GHC/TypeLits/Printf.hs
--- a/src/GHC/TypeLits/Printf.hs
+++ b/src/GHC/TypeLits/Printf.hs
@@ -27,102 +27,30 @@
 --
 -- An extensible and type-safe printf from parsing GHC TypeLits Symbol
 -- literals, matching the semantics of 'P.printf' from "Text.Printf" in
--- /base/.  The difference is that the variants here will always fail to
+-- /base/.  The difference is that your 'printf's will always fail to
 -- compile if given arguments of the wrong type (or too many or too little
--- arguments).  Most of the variants also provide useful type feedback,
--- telling you the type of arguments it expects and how many when queried
--- with @:t@ or with typed holes.  See documentation in "Text.Printf" for
--- details on how this formats items of various types, and the differences
--- with C @printf(3)@.
---
--- There are three main calling conventions supported:
---
--- >>> putStrLn $ printf @"You have %.2f dollars, %s" 3.62 "Luigi"
--- You have 3.62 dollars, Luigi
--- >>> putStrLn $ pprintf @"You have %.2f dollars, %s" (PP 3.62) (PP "Luigi")
--- You have 3.62 dollars, Luigi
--- >>> putStrLn $ rprintf @"You have %.2f dollars, %s" (3.62 :% "Luigi" :% RNil)
--- You have 3.62 dollars, Luigi
---
--- Now comparing their types:
---
--- >>> :t printf @"You have %.2f dollars, %s" 3.62 "Luigi"
--- FormatFun '[ .... ] fun => fun
--- >>> :t pprintf @"You have %.2f dollars, %s" 3.62 "Luigi"
--- PP "f" -> PP "s" -> String
--- >>> :t rprintf @"You have %.2f dollars, %s" 3.62 "Luigi"
--- FormatArgs '["f", "s"] -> String
---
--- *   The type of `printf` doesn't tell you immediately what you you need.
---     However, if you do try to use it, the type errors will guide you
---     along the way, iteratively.
---
---     >>> printf @"You have %.2f dollars, %s"
---     -- ERROR: Call to printf missing argument fulfilling "%.2f"
---     -- Either provide an argument or rewrite the format string to not expect
---     -- one.
---
---     >>> printf @"You have %.2f dollars, %s" 3.62
---     -- ERROR: Call to printf missing argument fulfilling "%s"
---     -- Either provide an argument or rewrite the format string to not expect
---     -- one.
---
---     >>> printf @"You have %.2f dollars, %s" 3.62 "Luigi"
---     You have 3.62 dollars, Luigi
---
---     >>> printf @"You have %.2f dollars, %s" 3.62 "Luigi" 72
---     -- ERROR: An extra argument of type Integer was given to a call to printf
---     -- Either remove the argument, or rewrite the format string to include the
---     -- appropriate hole.
---
--- *   For 'pprintf', it shows you need two arguments: A @'PP' "f"@ (which
---     is a value that supports being formatted by @f@) like @PP 3.62@, and
---     a @'PP' "s"@, like @PP "Luigi"@.
---
--- *   'rprintf' tells you you need a two-item hlist (from
---     "Data.Vinyl.Core"), where the first item implements @f@ and the
---     second item implements @s@: @3.62 ':%' "Luigi" :% 'RNil'@ will do.
---
--- The following table summarizes the features and drawbacks of each
--- method:
---
--- +-----------+------------------+--------------------+----------------------+
--- | Method    | True Polyarity   | Naked Arguments    | Type feedback        |
--- +===========+==================+====================+======================+
--- | 'printf'  | Yes              | Yes                | Partial (via errors) |
--- +-----------+------------------+--------------------+----------------------+
--- | 'pprintf' | Yes              | No (requires 'PP') | Yes                  |
--- +-----------+------------------+--------------------+----------------------+
--- | 'rprintf' | No (HList-based) | Yes                | Yes                  |
--- +-----------+------------------+--------------------+----------------------+
+-- arguments).  It also allows you to use types to help your development,
+-- by telling you the type of arguments it expects and how many when
+-- queried with @:t@ or with typed holes. See documentation in
+-- "Text.Printf" for details on how this formats items of various types,
+-- and the differences with C @printf(3)@.
 --
--- /Ideally/ we would have a solution that has all three.  However, as of
--- now, we have a "pick two" sort of situation.  Suggestions are definitely
--- welcome, however, if you find something that satisfies all three
--- benefits while still allowing for polymorphism!
+-- See 'printf' for the main function.
 --
--- You can extend functionality with formatting for your own types by
--- providing instances of @FormatType@.
+-- You can extend functionality with formatting for your own types by providing
+-- instances of 'FormatType'.
 --
 -- Also in this module is 'pfmt', which allows you to format individual
 -- items according to a single format specifier.
-
+--
 module GHC.TypeLits.Printf (
-  -- * Formattable things
-    FormatType(..)
-  , SChar
   -- * Printf
-  -- ** Unguarded polyarity
-  , printf, printf_
+    printf, printf_
   , PHelp, pHelp
   , FormatFun
-  -- ** Guarded polyarity
-  , pprintf
-  , pprintf_
-  , PP(..)
-  -- ** List-based polyarity
-  , rprintf, rprintf_
-  , Rec((:%), RNil), FormatArgs
+  -- * Formattable things
+  , FormatType(..)
+  , SChar
   -- * Single item
   , pfmt
   , PFmt
@@ -130,125 +58,56 @@
   ) where
 
 import           Data.Proxy
-import           Data.Vinyl
-import           Data.Vinyl.Curry
 import           GHC.TypeLits.Printf.Internal
 
--- | Type-safe printf with faked polyarity.  Pass in a "list" of arguments
--- (using ':%' and 'RNil'), instead of as multiple arguments.  Call it like
--- @'rprintf' \@"you have %.02f dollars, %s"@.
---
--- >>> :t rprintf @"You have %.2f dollars, %s"
--- FormatArgs '["f", "s"] -> String
---
--- This means that it is expecting something that can be printed with @f@
--- and something that can be printed with @s@.  We can provide a 'Double'
--- and a 'String':
+-- | "Type-safe printf". Call it like @'printf' \@"you have %.02f dollars, %s"@.
 --
--- >>> putStrLn $ rprintf @"You have %.2f dollars, %s" (3.62 ':%' "Luigi" :% 'RNil')
+-- >>> putStrLn $ printf @"You have %.2f dollars, %s" 3.62 "Luigi"
 -- You have 3.62 dollars, Luigi
 --
--- See 'pprintf' for a version with true polyarity and good clear types,
--- but requires wrapping its arguments, and 'printf' for a version with
--- true polyarity but less clear types.  Also see top-level module
--- documentation  "GHC.TypeLits.Printf" for a more comprehensive summary.
-rprintf :: forall str ps. RPrintf str ps => FormatArgs ps -> String
-rprintf = rprintf_ (Proxy @str)
-
--- | Pattern and constructor allowing you to construct a 'FormatArgs'.
---
--- To construct a @'FormatArgs' '["f", "s"]@, for instance, you need to
--- give a value formattable by @f@ and a value formattable by @s@, given
--- like a linked list, with ':%' for cons and 'RNil' for nil.
---
--- @
--- 3.62 ':%' "Luigi" :% 'RNil'
--- @
---
--- (This should evoke the idea of of @3.62 : "Luigi" : []@, even though the
--- latter is not possible in Haskell)
-pattern (:%) :: () => FormatType c a => a -> FormatArgs cs -> FormatArgs (c ': cs)
-pattern x :% xs = PP x :& xs
-infixr 7 :%
-{-# COMPLETE (:%) #-}
-
--- | A version of 'pprintf' taking an explicit proxy, which allows usage
--- without /TypeApplications/
---
--- >>> :t pprintf_ (Proxy :: Proxy "You have %.2f dollars, %s")
--- PP "f" -> PP "s" -> String
-pprintf_ :: forall str ps p. (RPrintf str ps, RecordCurry ps) => p str -> CurriedF PP ps String
-pprintf_ p = rcurry @ps (rprintf_ p)
-
--- | Type-safe printf with true guarded polyarity.  Call it like @'pprintf'
--- \@"you have %.02f dollars, %s"@.
---
--- A call to printf on a valid string will /always/ give a well-defined
--- type for a function in return:
---
--- >>> :t pprintf @"You have %.2f dollars, %s"
--- PP "f" -> PP "s" -> String
---
--- You can always query the type, and get a well-defined type back, which
--- you can utilize using typed holes or other type-guided development
--- techniques.
+-- Looking at its type:
 --
--- To give 'pprintf' its arguments, however, they must be wrapped in 'PP':
+-- >>> :t printf @"You have %.2f dollars, %s"
+-- (FormatType "f" arg1, FormatType "s" arg2)
+--   => arg1 -> arg2 -> String
 --
--- >>> putStrLn $ pprintf @"You have %.2f dollars, %s" (PP 3.62) (PP "Luigi")
--- You have 3.62 dollars, Luigi
+-- It tells you that the result is an @arg1 -> arg2 -> 'String'@: take two
+-- arguments, and return a 'String'.  The first argument must be an instance of
+-- @'FormatType' "f"@ (things that can be formatted by @%f@) and the second argument
+-- must be an instance of @'FormatType' "s"@ (things that can be formatted by @%s@).
 --
--- See 'printf' for a polyariadic method that doesn't require 'PP' on its
--- inputs, but with a less helpful type signature, and 'rprintf' for
--- a fake-polyariadic method that doesn't require 'PP', but requires
--- arguments in a single list instead. Also see top-level module
--- documentation  "GHC.TypeLits.Printf" for a more comprehensive summary.
-pprintf :: forall str ps. (RPrintf str ps, RecordCurry ps) => CurriedF PP ps String
-pprintf = pprintf_ @str @ps (Proxy @str)
-
--- | Type-safe printf with true naked polyarity.  Call it like @'printf'
--- \@"you have %.02f dollars, %s"@.
+-- We can see this in action by progressively applying arguments:
 --
--- >>> putStrLn $ printf @"You have %.2f dollars, %s" 3.62 "Luigi"
--- You have 3.62 dollars, Luigi
+-- >>> :t printf @"You have %.2f dollars, %s" 3.62
+-- FormatType "s" arg1 => arg1 -> String
+-- >>> :t printf @"You have %.2f dollars, %s" 3.62 "Luigi"
+-- String
 --
--- While the type of @'printf' \@"my fmt string"@ isn't going to be very
--- helpful, the error messages should help guide you along the way:
+-- The type errors for forgetting to apply an argument (or applying too many
+-- arguments) are pretty clear:
 --
--- >>> printf @"You have %.2f dollars, %s"
+-- >>> putStrLn $ printf @"You have %.2f dollars, %s"
 -- -- ERROR: Call to printf missing argument fulfilling "%.2f"
 -- -- Either provide an argument or rewrite the format string to not expect
 -- -- one.
---
--- >>> printf @"You have %.2f dollars, %s" 3.62
+-- >>> putStrLn $ printf @"You have %.2f dollars, %s" 3.62
 -- -- ERROR: Call to printf missing argument fulfilling "%s"
 -- -- Either provide an argument or rewrite the format string to not expect
 -- -- one.
---
--- >>> printf @"You have %.2f dollars, %s" 3.62 "Luigi"
+-- >>> putStrLn $ printf @"You have %.2f dollars, %s" 3.62 "Luigi"
 -- You have 3.62 dollars, Luigi
---
--- >>> printf @"You have %.2f dollars, %s" 3.62 "Luigi" 72
+-- >>> putStrLn $ printf @"You have %.2f dollars, %s" 3.62 "Luigi" 72
 -- -- ERROR: An extra argument of type Integer was given to a call to printf
 -- -- Either remove the argument, or rewrite the format string to include the
 -- -- appropriate hole.
 --
--- If you're having problems getting the error messages to give helpful
--- feedback, try using 'pHelp':
+-- If you want to see some useful error messages for feedback, 'pHelp' can
+-- be useful:
 --
 -- >>> pHelp $ printf @"You have %.2f dollars, %s" 3.62
 -- -- ERROR: Call to printf missing argument fulfilling "%s"
 -- -- Either provide an argument or rewrite the format string to not expect
 -- -- one.
---
--- 'pHelp' can give the type system the nudge it needs to provide good
--- errors.
---
--- See 'pprintf' for a version of this with nicer types and type errors,
--- but requires wrapping arguments, and 'rprintf' for a version of this
--- with "fake" polyarity, taking a list as input instead. Also see
--- top-level module documentation  "GHC.TypeLits.Printf" for a more
--- comprehensive summary.
 --
 -- Note that this also supports the "interpret as an IO action to print out
 -- results" functionality that "Text.Printf" supports.  This also supports
diff --git a/src/GHC/TypeLits/Printf/Internal.hs b/src/GHC/TypeLits/Printf/Internal.hs
--- a/src/GHC/TypeLits/Printf/Internal.hs
+++ b/src/GHC/TypeLits/Printf/Internal.hs
@@ -49,10 +49,6 @@
   , Demote
   , Reflect(..)
   , FormatType(..)
-  , PP(..)
-  , RPrintf(..)
-  , FormatArgs
-  , RFormat(..)
   , Printf(..)
   , FormatFun(..)
   , PFmt(..)
@@ -64,7 +60,6 @@
 import           Data.Int
 import           Data.Proxy
 import           Data.Symbol.Utils
-import           Data.Vinyl
 import           Data.Word
 import           GHC.OverloadedLabels
 import           GHC.TypeLits
@@ -235,141 +230,36 @@
 instance FormatType "v" TL.Text where
     formatArg _ = P.formatArg . TL.unpack
 
--- | Required wrapper around inputs to 'GHC.TypeLits.Printf.pprintf'
--- (guarded polyarity).  See documentation for
--- 'GHC.TypeLits.Printf.pprintf' for examples of usage.
---
--- You can "wrap" any value in 'PP' as long as it can be formatted as the
--- format type indicated.
---
--- For example, to make a @'PP' "f"@, you can use @'PP' 3.5@ or @'PP'
--- 94.2@, but not @'PP' (3 :: Int)@ or @'PP' "hello"@.  To make a value of
--- type @'PP' c@, you must wrap a value that can be formatted via @c@.
-data PP (c :: SChar) = forall a. FormatType c a => PP a
-
--- | A heterogeneous list (from "Data.Vinyl.Core") used for calling with
--- 'GHC.TypeLits.Printf.rprintf'.  Instead of supplying the inputs as
--- different arguments, we can gather all the inputs into a single list to
--- give to 'GHC.TypeLits.Printf.rprintf'.
---
--- >>> :t rprintf @"You have %.2f dollars, %s"
--- FormatArgs '["f", "s"] -> String
---
--- To construct a @'FormatArgs' '["f", "s"]@, you need to give a value
--- formattable by @f@ and a value formattable by @s@, given like a linked
--- list, with 'GHC.TypeLits.Printf.:%' for cons and 'RNil' for nil.
---
--- >>> putStrLn $ rprintf @"You have %.2f dollars, %s" (3.62 :% "Luigi" :% RNil)
--- You have 3.62 dollars, Luigi
---
--- (This should evoke the idea of of @3.62 : "Luigi" : []@, even though the
--- latter is not possible in Haskell)
-type FormatArgs = Rec PP
-
-class RFormat (ffs :: [Either Symbol FieldFormat]) (ps :: [SChar]) | ffs -> ps where
-    rformat :: p ffs -> FormatArgs ps -> ShowS
-
-instance RFormat '[] '[] where
-    rformat _ _ = id
-
-instance (KnownSymbol str, RFormat ffs ps) => RFormat ('Left str ': ffs) ps where
-    rformat _ r = showString (symbolVal (Proxy @str))
-                . rformat (Proxy @ffs) r
-
-instance (Reflect ff, ff ~ 'FF f w p m c, RFormat ffs ps) => RFormat ('Right ff ': ffs) (c ': ps) where
-    rformat _ (PP x :& xs) = formatArg (Proxy @c) x ff
-                           . rformat (Proxy @ffs) xs
-      where
-        ff = reflect (Proxy @ff)
-
-class RPrintf (str :: Symbol) ps where
-    -- | A version of 'GHC.TypeLits.Printf.rprintf' taking an explicit
-    -- proxy, which allows usage without /TypeApplications/
-    --
-    -- >>> :t rprintf_ (Proxy :: Proxy "You have %.2f dollars, %s")
-    -- FormatArgs '["f", "s"] -> String
-    rprintf_ :: p str -> FormatArgs ps -> String
-
-instance (Listify str lst, ffs ~ ParseFmtStr_ lst, RFormat ffs ps) => RPrintf str ps where
-    rprintf_ _ = ($ "") . rformat (Proxy @ffs)
-
 -- | The typeclass supporting polyarity used by
 -- 'GHC.TypeLits.Printf.printf'. It works in mostly the same way as
 -- 'P.PrintfType' from "Text.Printf", and similar the same as
--- 'Data.Symbol.Examples.Printf.FormatF'.
---
--- Ideally, you will never have to run into this typeclass or have to deal
--- with it.  It will come up if you ask for the type of
--- 'GHC.TypeLits.Printf.printf', or sometimes if you give the wrong number
--- or type of arguments to it.
---
--- >>> :t printf @"You have %.2f dollars, %s"
--- FormatFun '[ Right ..., 'Left " dollars ", 'Right ...] fun => fun
+-- 'Data.Symbol.Examples.Printf.FormatF'.  Ideally, you will never have to
+-- run into this typeclass or have to deal with it directly.
 --
 -- Every item in the first argument of 'FormatFun' is a chunk of the
 -- formatting string, split between format holes ('Right') and string
--- chunks ('Left').  You can successively "eliminate" them by providing
--- more arguments that implement each hole:
---
--- >>> :t printf @"You have %.2f dollars, %s" 3.62
--- FormatFun '[ Right ...] fun => fun
---
--- Until you you finally fill all the holes:
---
--- >>> :t printf @"You have %.2f dollars, %s" 3.62 "Luigi"
--- FormatFun '[] t => t
---
--- at which point you may use it as a 'String' or @'IO' ()@, in the same
--- way that "Text.Printf" works.  We also support using strict 'T.Text'
--- lazy 'TL.Text' as well.
---
--- So, while it's possible to reason with this using the types, it's
--- usually more difficult than with 'pprintf' and 'rprintf'.
---
--- This is why, instead of reasoning with this using its types, it's easier
--- to reason with it using the errors instead:
---
--- >>> printf @"You have %.2f dollars, %s"
--- -- ERROR: Call to printf missing argument fulfilling "%.2f"
--- -- Either provide an argument or rewrite the format string to not expect
--- -- one.
---
--- >>> printf @"You have %.2f dollars, %s" 3.62
--- -- ERROR: Call to printf missing argument fulfilling "%s"
--- -- Either provide an argument or rewrite the format string to not expect
--- -- one.
---
--- >>> printf @"You have %.2f dollars, %s" 3.62 "Luigi"
--- You have 3.62 dollars, Luigi
---
--- >>> printf @"You have %.2f dollars, %s" 3.62 "Luigi" 72
--- -- ERROR: An extra argument of type Integer was given to a call to printf
--- -- Either remove the argument, or rewrite the format string to include the
--- -- appropriate hole.
+-- chunks ('Left').
 --
--- If you're having problems getting the error messages to give helpful
--- feedback, try using 'pHelp':
+-- If you want to see some useful error messages for feedback, 'pHelp' can
+-- be useful:
 --
 -- >>> pHelp $ printf @"You have %.2f dollars, %s" 3.62
 -- -- ERROR: Call to printf missing argument fulfilling "%s"
 -- -- Either provide an argument or rewrite the format string to not expect
 -- -- one.
---
--- 'pHelp' can give the type system the nudge it needs to provide good
--- errors.
 class FormatFun (ffs :: [Either Symbol FieldFormat]) fun where
     formatFun :: p ffs -> String -> fun
 
--- | A useful token for helping the type system give useful errors for
--- 'printf':
+-- | A useful tool for helping the type system give useful errors for
+-- 'GHC.TypeLits.Printf.printf':
 --
 -- >>> printf @"You have ".2f" dollars, %s" 3.26 :: PHelp
 -- -- ERROR: Call to printf missing argument fulfilling "%s"
 -- -- Either provide an argument or rewrite the format string to not expect
 -- -- one.
 --
--- Usually things should work out on their own without needing this ... but
--- sometimes the type system could need a nudge.
+-- Mostly useful if you want to force a useful type error to help see what
+-- is going on.
 --
 -- See also 'pHelp'
 newtype PHelp = PHelp {
@@ -381,12 +271,12 @@
     -- -- Either provide an argument or rewrite the format string to not expect
     -- -- one.
     --
-    -- Usually things would work out on their own without needing this ...
-    -- but sometimes the type system could need a nudge.
+    -- Mostly useful if you want to force a useful type error to help see
+    -- what is going on.
     pHelp :: String
   }
 
-instance (a ~ Char) => FormatFun '[] [a] where
+instance {-# INCOHERENT #-} (a ~ String) => FormatFun '[] a where
     formatFun _ = id
 instance (a ~ Char) => FormatFun '[] PHelp where
     formatFun _ = PHelp
@@ -414,7 +304,7 @@
 instance (KnownSymbol str, FormatFun ffs fun) => FormatFun ('Left str ': ffs) fun where
     formatFun _ str = formatFun (Proxy @ffs) (str ++ symbolVal (Proxy @str))
 
-instance (Reflect ff, ff ~ 'FF f w p m c, FormatType c a, FormatFun ffs fun) => FormatFun ('Right ff ': ffs) (a -> fun) where
+instance {-# INCOHERENT #-} (afun ~ (arg -> fun), Reflect ff, ff ~ 'FF f w p m c, FormatType c arg, FormatFun ffs fun) => FormatFun ('Right ff ': ffs) afun where
     formatFun _ str x = formatFun (Proxy @ffs) (str ++ formatArg (Proxy @c) x ff "")
       where
         ff = reflect (Proxy @ff)
@@ -449,7 +339,7 @@
 instance (Listify str lst, ffs ~ ParseFmtStr_ lst, FormatFun ffs fun) => Printf str fun where
     printf_ _ = formatFun (Proxy @ffs) ""
 
--- | Utility type powering 'pfmt'.  See dcumentation for 'pfmt' for more
+-- | Utility type powering 'pfmt'.  See documentation for 'pfmt' for more
 -- information on usage.
 --
 -- Using /OverloadedLabels/, you never need to construct this directly
@@ -460,7 +350,7 @@
 
 -- | A version of 'mkPFmt' that takes an explicit proxy input.
 --
--- >>> pfmt (mkPFmt_ (Proxy :: Proxy ".2f") 3.6234124
+-- >>> pfmt (mkPFmt_ (Proxy :: Proxy ".2f")) 3.6234124
 -- "3.62"
 mkPFmt_
     :: forall str lst ff f w q m c p. (Listify str lst, ff ~ ParseFmt_ lst, Reflect ff, ff ~ 'FF f w q m c)
@@ -510,6 +400,6 @@
 --
 -- (which should be possible in GHC 8.10+)
 --
--- Note that the format string does not include the leading @%@.
+-- Note that the format string should not include the leading @%@.
 pfmt :: forall c a. FormatType c a => PFmt c -> a -> String
 pfmt (PFmt ff) x = formatArg (Proxy @c) x ff ""
diff --git a/typelits-printf.cabal b/typelits-printf.cabal
--- a/typelits-printf.cabal
+++ b/typelits-printf.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: b5b3f760af5c7c80862e1246320b78e43abe2900acd93e8fe21ace4920fcc4ed
+-- hash: ab8bb88b98e9aefe5c55f593c26d691a8125a6014b60204b85fda8f8ea01e90b
 
 name:           typelits-printf
-version:        0.1.1.0
+version:        0.2.0.0
 synopsis:       Type-safe printf from parsing GHC TypeLits Symbol
 description:    An extensible and type-safe printf from parsing GHC TypeLits Symbol
                 literals, matching the semantics of 'P.printf' from "Text.Printf" in /base/.
@@ -50,5 +50,4 @@
       base >=4.13 && <5
     , symbols >=0.3 && <0.4
     , text
-    , vinyl >=0.12.1
   default-language: Haskell2010
