-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Type-safe printf from parsing GHC TypeLits Symbol -- -- 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 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 README and documentation of GHC.TypeLits.Printf for more -- information @package typelits-printf @version 0.1.0.0 -- | Internal workings of the printf mechanisms, exposed for potential -- debugging purposes. -- -- Please do not use this module for anything besides debugging, as is -- definitely very unstable and might go away or change dramatically -- between versions. module GHC.TypeLits.Printf.Internal type ParseFmtStr str = EvalParser FmtStrParser str type ParseFmtStr_ str = EvalParser_ FmtStrParser str type ParseFmt str = EvalParser FFParser str type ParseFmt_ str = EvalParser_ FFParser str -- | Whether to left-adjust or zero-pad a field. These are mutually -- exclusive, with LeftAdjust taking precedence. data FormatAdjustment LeftAdjust :: FormatAdjustment ZeroPad :: FormatAdjustment type family ShowFormat (x :: k) :: Symbol -- | How to handle the sign of a numeric field. These are mutually -- exclusive, with SignPlus taking precedence. data FormatSign SignPlus :: FormatSign SignSpace :: FormatSign data WidthMod WMhh :: WidthMod WMh :: WidthMod WMl :: WidthMod WMll :: WidthMod WML :: WidthMod data Flags Flags :: Maybe FormatAdjustment -> Maybe FormatSign -> Bool -> Flags [fAdjust] :: Flags -> Maybe FormatAdjustment [fSign] :: Flags -> Maybe FormatSign [fAlternate] :: Flags -> Bool type EmptyFlags = 'Flags 'Nothing 'Nothing 'False data FieldFormat FF :: Flags -> Maybe Nat -> Maybe Nat -> Maybe WidthMod -> SChar -> FieldFormat [fmtFlags] :: FieldFormat -> Flags [fmtWidth] :: FieldFormat -> Maybe Nat [fmtPrecision] :: FieldFormat -> Maybe Nat [fmtWidthMod] :: FieldFormat -> Maybe WidthMod [fmtChar] :: FieldFormat -> SChar -- | A type synonym for a single-character symbol. Ideally this would just -- be Char, but we don't have chars at the type level. So, if you -- see SChar in a type signature, it means that it's expected to -- be a symbol/string with only one single character. type SChar = Symbol type family Demote k = a | a -> k class Reflect (x :: a) reflect :: Reflect x => p x -> Demote a -- | Typeclass associating format types (d, f, etc.) with -- the types that can be formatted by them. -- -- You can extend the printf methods here for your own types by writing -- your instances here. class FormatType (t :: SChar) a formatArg :: FormatType t a => p t -> a -> FieldFormat -> ShowS formatArg :: (FormatType t a, PrintfArg a) => p t -> a -> FieldFormat -> ShowS -- | Required wrapper around inputs to pprintf (guarded polyarity). -- See documentation for 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) PP :: a -> PP (c :: SChar) class RPrintf (str :: Symbol) ps -- | A version of rprintf taking an explicit proxy, which allows -- usage without TypeApplications -- --
--   >>> :t rprintf_ (Proxy :: Proxy "You have %.2f dollars, %s")
--   FormatArgs '["f", "s"] -> String
--   
rprintf_ :: RPrintf str ps => p str -> FormatArgs ps -> String -- | A heterogeneous list (from Data.Vinyl.Core) used for calling -- with rprintf. Instead of supplying the inputs as different -- arguments, we can gather all the inputs into a single list to give to -- 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 :% 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 rformat :: RFormat ffs ps => p ffs -> FormatArgs ps -> ShowS class Printf (str :: Symbol) fun -- | A version of printf taking an explicit proxy, which allows -- usage without TypeApplications -- --
--   >>> putStrLn $ printf_ (Proxy :: Proxy "You have %.2f dollars, %s") 3.62 "Luigi"
--   You have 3.62 dollars, Luigi
--   
printf_ :: Printf str fun => p str -> fun -- | The typeclass supporting polyarity used by printf. It works in -- mostly the same way as PrintfType from Text.Printf, and -- similar the same as 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 -- 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
--   
-- -- 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 Text lazy 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.
--   
-- -- If you're having problems getting the error messages to give helpful -- feedback, try using pHelp: -- --
--   >>> 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 formatFun :: FormatFun ffs fun => p ffs -> String -> fun -- | Utility type powering pfmt. See dcumentation for pfmt -- for more information on usage. -- -- Using OverloadedLabels, you never need to construct this -- directly can just write #f and a PFmt "f" -- will be generated. You can also create this using mkPFmt or -- mkPFmt_, in the situations where OverloadedLabels -- doesn't work or is not wanted. newtype PFmt c PFmt :: FieldFormat -> PFmt c -- | Parse and run a single format hole on a single vale. Can be -- useful for formatting individual items or for testing your own custom -- instances of FormatType. -- -- Usually meant to be used with OverloadedLabels: -- --
--   >>> pfmt #f 3.62
--   "3.62"
--   
-- -- However, current versions of GHC disallow labels that aren't valid -- identifier names, disallowing things like pfmt #.2f -- 3.62. While there is an -- <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst -- approved proposal> that allows this, if you are using an earlier -- GHC version, you can get around this using mkPFmt: -- --
--   >>> pfmt (mkPFmt @".2f") 3.6234124
--   "3.62"
--   
-- -- Ideally we'd want to be able to write -- --
--   >>> pfmt #.2f 3.6234124
--   "3.62"
--   
-- -- (which should be possible in GHC 8.10+) -- -- Note that the format string does not include the leading %. pfmt :: forall c a. FormatType c a => PFmt c -> a -> String -- | Useful for using pfmt without OverloadedLabels, or also -- when passing format specifiers that aren't currently allowed with -- OverloadedLabels until GHC 8.10+ (like #.2f). -- --
--   >>> pfmt (mkPFmt @".2f") 3.6234124
--   "3.62"
--   
mkPFmt :: forall str lst ff f w q m c. (Listify str lst, ff ~ ParseFmt_ lst, Reflect ff, ff ~ 'FF f w q m c) => PFmt c -- | A version of mkPFmt that takes an explicit proxy input. -- --
--   >>> 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) => p str -> PFmt c -- | A useful token for helping the type system give useful errors for -- 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. -- -- See also pHelp newtype PHelp PHelp :: String -> PHelp -- | A useful helper function for helping the type system give useful -- errors for printf: -- --
--   >>> 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.
--   
-- -- Usually things would work out on their own without needing this ... -- but sometimes the type system could need a nudge. [pHelp] :: PHelp -> String instance (Data.Symbol.Utils.Listify str lst, ff GHC.Types.~ GHC.TypeLits.Printf.Parse.ParseFmt_ lst, GHC.TypeLits.Printf.Parse.Reflect ff, ff GHC.Types.~ 'GHC.TypeLits.Printf.Parse.FF f w p m c) => GHC.OverloadedLabels.IsLabel str (GHC.TypeLits.Printf.Internal.PFmt c) instance (Data.Symbol.Utils.Listify str lst, ffs GHC.Types.~ GHC.TypeLits.Printf.Parse.ParseFmtStr_ lst, GHC.TypeLits.Printf.Internal.FormatFun ffs fun) => GHC.TypeLits.Printf.Internal.Printf str fun instance (TypeError ...) => GHC.TypeLits.Printf.Internal.FormatFun ('Data.Either.Right ff : ffs) GHC.Base.String instance (TypeError ...) => GHC.TypeLits.Printf.Internal.FormatFun ('Data.Either.Right ff : ffs) () instance (TypeError ...) => GHC.TypeLits.Printf.Internal.FormatFun ('Data.Either.Right ff : ffs) Data.Text.Internal.Text instance (TypeError ...) => GHC.TypeLits.Printf.Internal.FormatFun ('Data.Either.Right ff : ffs) Data.Text.Internal.Lazy.Text instance (TypeError ...) => GHC.TypeLits.Printf.Internal.FormatFun ('Data.Either.Right ff : ffs) GHC.TypeLits.Printf.Internal.PHelp instance (TypeError ...) => GHC.TypeLits.Printf.Internal.FormatFun ('Data.Either.Right ff : ffs) (GHC.Types.IO a) instance (a GHC.Types.~ GHC.Types.Char) => GHC.TypeLits.Printf.Internal.FormatFun '[] GHC.TypeLits.Printf.Internal.PHelp instance (a GHC.Types.~ GHC.Types.Char) => GHC.TypeLits.Printf.Internal.FormatFun '[] [a] instance (a GHC.Types.~ GHC.Types.Char) => GHC.TypeLits.Printf.Internal.FormatFun '[] Data.Text.Internal.Text instance (a GHC.Types.~ GHC.Types.Char) => GHC.TypeLits.Printf.Internal.FormatFun '[] Data.Text.Internal.Lazy.Text instance (a GHC.Types.~ ()) => GHC.TypeLits.Printf.Internal.FormatFun '[] (GHC.Types.IO a) instance (TypeError ...) => GHC.TypeLits.Printf.Internal.FormatFun '[] () instance (TypeError ...) => GHC.TypeLits.Printf.Internal.FormatFun '[] (a -> b) instance (GHC.TypeLits.KnownSymbol str, GHC.TypeLits.Printf.Internal.FormatFun ffs fun) => GHC.TypeLits.Printf.Internal.FormatFun ('Data.Either.Left str : ffs) fun instance (GHC.TypeLits.Printf.Parse.Reflect ff, ff GHC.Types.~ 'GHC.TypeLits.Printf.Parse.FF f w p m c, GHC.TypeLits.Printf.Internal.FormatType c a, GHC.TypeLits.Printf.Internal.FormatFun ffs fun) => GHC.TypeLits.Printf.Internal.FormatFun ('Data.Either.Right ff : ffs) (a -> fun) instance (Data.Symbol.Utils.Listify str lst, ffs GHC.Types.~ GHC.TypeLits.Printf.Parse.ParseFmtStr_ lst, GHC.TypeLits.Printf.Internal.RFormat ffs ps) => GHC.TypeLits.Printf.Internal.RPrintf str ps instance GHC.TypeLits.Printf.Internal.RFormat '[] '[] instance (GHC.TypeLits.KnownSymbol str, GHC.TypeLits.Printf.Internal.RFormat ffs ps) => GHC.TypeLits.Printf.Internal.RFormat ('Data.Either.Left str : ffs) ps instance (GHC.TypeLits.Printf.Parse.Reflect ff, ff GHC.Types.~ 'GHC.TypeLits.Printf.Parse.FF f w p m c, GHC.TypeLits.Printf.Internal.RFormat ffs ps) => GHC.TypeLits.Printf.Internal.RFormat ('Data.Either.Right ff : ffs) (c : ps) instance GHC.TypeLits.Printf.Internal.FormatType "c" GHC.Types.Char instance GHC.TypeLits.Printf.Internal.FormatType "c" GHC.Word.Word8 instance GHC.TypeLits.Printf.Internal.FormatType "c" GHC.Word.Word16 instance GHC.TypeLits.Printf.Internal.FormatType "d" GHC.Types.Char instance GHC.TypeLits.Printf.Internal.FormatType "d" GHC.Types.Int instance GHC.TypeLits.Printf.Internal.FormatType "d" GHC.Int.Int8 instance GHC.TypeLits.Printf.Internal.FormatType "d" GHC.Int.Int16 instance GHC.TypeLits.Printf.Internal.FormatType "d" GHC.Int.Int32 instance GHC.TypeLits.Printf.Internal.FormatType "d" GHC.Int.Int64 instance GHC.TypeLits.Printf.Internal.FormatType "d" GHC.Integer.Type.Integer instance GHC.TypeLits.Printf.Internal.FormatType "d" GHC.Natural.Natural instance GHC.TypeLits.Printf.Internal.FormatType "d" GHC.Types.Word instance GHC.TypeLits.Printf.Internal.FormatType "d" GHC.Word.Word8 instance GHC.TypeLits.Printf.Internal.FormatType "d" GHC.Word.Word16 instance GHC.TypeLits.Printf.Internal.FormatType "d" GHC.Word.Word32 instance GHC.TypeLits.Printf.Internal.FormatType "d" GHC.Word.Word64 instance GHC.TypeLits.Printf.Internal.FormatType "o" GHC.Types.Char instance GHC.TypeLits.Printf.Internal.FormatType "o" GHC.Types.Int instance GHC.TypeLits.Printf.Internal.FormatType "o" GHC.Int.Int8 instance GHC.TypeLits.Printf.Internal.FormatType "o" GHC.Int.Int16 instance GHC.TypeLits.Printf.Internal.FormatType "o" GHC.Int.Int32 instance GHC.TypeLits.Printf.Internal.FormatType "o" GHC.Int.Int64 instance GHC.TypeLits.Printf.Internal.FormatType "o" GHC.Integer.Type.Integer instance GHC.TypeLits.Printf.Internal.FormatType "o" GHC.Natural.Natural instance GHC.TypeLits.Printf.Internal.FormatType "o" GHC.Types.Word instance GHC.TypeLits.Printf.Internal.FormatType "o" GHC.Word.Word8 instance GHC.TypeLits.Printf.Internal.FormatType "o" GHC.Word.Word16 instance GHC.TypeLits.Printf.Internal.FormatType "o" GHC.Word.Word32 instance GHC.TypeLits.Printf.Internal.FormatType "o" GHC.Word.Word64 instance GHC.TypeLits.Printf.Internal.FormatType "x" GHC.Types.Int instance GHC.TypeLits.Printf.Internal.FormatType "x" GHC.Int.Int8 instance GHC.TypeLits.Printf.Internal.FormatType "x" GHC.Int.Int16 instance GHC.TypeLits.Printf.Internal.FormatType "x" GHC.Int.Int32 instance GHC.TypeLits.Printf.Internal.FormatType "x" GHC.Int.Int64 instance GHC.TypeLits.Printf.Internal.FormatType "x" GHC.Integer.Type.Integer instance GHC.TypeLits.Printf.Internal.FormatType "x" GHC.Natural.Natural instance GHC.TypeLits.Printf.Internal.FormatType "x" GHC.Types.Word instance GHC.TypeLits.Printf.Internal.FormatType "x" GHC.Word.Word8 instance GHC.TypeLits.Printf.Internal.FormatType "x" GHC.Word.Word16 instance GHC.TypeLits.Printf.Internal.FormatType "x" GHC.Word.Word32 instance GHC.TypeLits.Printf.Internal.FormatType "x" GHC.Word.Word64 instance GHC.TypeLits.Printf.Internal.FormatType "X" GHC.Types.Char instance GHC.TypeLits.Printf.Internal.FormatType "X" GHC.Types.Int instance GHC.TypeLits.Printf.Internal.FormatType "X" GHC.Int.Int8 instance GHC.TypeLits.Printf.Internal.FormatType "X" GHC.Int.Int16 instance GHC.TypeLits.Printf.Internal.FormatType "X" GHC.Int.Int32 instance GHC.TypeLits.Printf.Internal.FormatType "X" GHC.Int.Int64 instance GHC.TypeLits.Printf.Internal.FormatType "X" GHC.Integer.Type.Integer instance GHC.TypeLits.Printf.Internal.FormatType "X" GHC.Natural.Natural instance GHC.TypeLits.Printf.Internal.FormatType "X" GHC.Types.Word instance GHC.TypeLits.Printf.Internal.FormatType "X" GHC.Word.Word8 instance GHC.TypeLits.Printf.Internal.FormatType "X" GHC.Word.Word16 instance GHC.TypeLits.Printf.Internal.FormatType "X" GHC.Word.Word32 instance GHC.TypeLits.Printf.Internal.FormatType "X" GHC.Word.Word64 instance GHC.TypeLits.Printf.Internal.FormatType "b" GHC.Types.Char instance GHC.TypeLits.Printf.Internal.FormatType "b" GHC.Types.Int instance GHC.TypeLits.Printf.Internal.FormatType "b" GHC.Int.Int8 instance GHC.TypeLits.Printf.Internal.FormatType "b" GHC.Int.Int16 instance GHC.TypeLits.Printf.Internal.FormatType "b" GHC.Int.Int32 instance GHC.TypeLits.Printf.Internal.FormatType "b" GHC.Int.Int64 instance GHC.TypeLits.Printf.Internal.FormatType "b" GHC.Integer.Type.Integer instance GHC.TypeLits.Printf.Internal.FormatType "b" GHC.Natural.Natural instance GHC.TypeLits.Printf.Internal.FormatType "b" GHC.Types.Word instance GHC.TypeLits.Printf.Internal.FormatType "b" GHC.Word.Word8 instance GHC.TypeLits.Printf.Internal.FormatType "b" GHC.Word.Word16 instance GHC.TypeLits.Printf.Internal.FormatType "b" GHC.Word.Word32 instance GHC.TypeLits.Printf.Internal.FormatType "b" GHC.Word.Word64 instance GHC.TypeLits.Printf.Internal.FormatType "u" GHC.Types.Char instance GHC.TypeLits.Printf.Internal.FormatType "u" GHC.Types.Int instance GHC.TypeLits.Printf.Internal.FormatType "u" GHC.Int.Int8 instance GHC.TypeLits.Printf.Internal.FormatType "u" GHC.Int.Int16 instance GHC.TypeLits.Printf.Internal.FormatType "u" GHC.Int.Int32 instance GHC.TypeLits.Printf.Internal.FormatType "u" GHC.Int.Int64 instance GHC.TypeLits.Printf.Internal.FormatType "u" GHC.Integer.Type.Integer instance GHC.TypeLits.Printf.Internal.FormatType "u" GHC.Natural.Natural instance GHC.TypeLits.Printf.Internal.FormatType "u" GHC.Types.Word instance GHC.TypeLits.Printf.Internal.FormatType "u" GHC.Word.Word8 instance GHC.TypeLits.Printf.Internal.FormatType "u" GHC.Word.Word16 instance GHC.TypeLits.Printf.Internal.FormatType "u" GHC.Word.Word32 instance GHC.TypeLits.Printf.Internal.FormatType "u" GHC.Word.Word64 instance GHC.TypeLits.Printf.Internal.FormatType "f" GHC.Types.Double instance GHC.TypeLits.Printf.Internal.FormatType "f" GHC.Types.Float instance GHC.TypeLits.Printf.Internal.FormatType "F" GHC.Types.Double instance GHC.TypeLits.Printf.Internal.FormatType "F" GHC.Types.Float instance GHC.TypeLits.Printf.Internal.FormatType "g" GHC.Types.Double instance GHC.TypeLits.Printf.Internal.FormatType "g" GHC.Types.Float instance GHC.TypeLits.Printf.Internal.FormatType "G" GHC.Types.Double instance GHC.TypeLits.Printf.Internal.FormatType "G" GHC.Types.Float instance GHC.TypeLits.Printf.Internal.FormatType "e" GHC.Types.Double instance GHC.TypeLits.Printf.Internal.FormatType "e" GHC.Types.Float instance GHC.TypeLits.Printf.Internal.FormatType "E" GHC.Types.Double instance GHC.TypeLits.Printf.Internal.FormatType "E" GHC.Types.Float instance GHC.TypeLits.Printf.Internal.FormatType "s" GHC.Base.String instance GHC.TypeLits.Printf.Internal.FormatType "s" Data.Text.Internal.Text instance GHC.TypeLits.Printf.Internal.FormatType "s" Data.Text.Internal.Lazy.Text instance GHC.TypeLits.Printf.Internal.FormatType "v" GHC.Types.Char instance GHC.TypeLits.Printf.Internal.FormatType "v" GHC.Types.Int instance GHC.TypeLits.Printf.Internal.FormatType "v" GHC.Int.Int8 instance GHC.TypeLits.Printf.Internal.FormatType "v" GHC.Int.Int16 instance GHC.TypeLits.Printf.Internal.FormatType "v" GHC.Int.Int32 instance GHC.TypeLits.Printf.Internal.FormatType "v" GHC.Int.Int64 instance GHC.TypeLits.Printf.Internal.FormatType "v" GHC.Integer.Type.Integer instance GHC.TypeLits.Printf.Internal.FormatType "v" GHC.Natural.Natural instance GHC.TypeLits.Printf.Internal.FormatType "v" GHC.Types.Word instance GHC.TypeLits.Printf.Internal.FormatType "v" GHC.Word.Word8 instance GHC.TypeLits.Printf.Internal.FormatType "v" GHC.Word.Word16 instance GHC.TypeLits.Printf.Internal.FormatType "v" GHC.Word.Word32 instance GHC.TypeLits.Printf.Internal.FormatType "v" GHC.Word.Word64 instance GHC.TypeLits.Printf.Internal.FormatType "v" GHC.Types.Double instance GHC.TypeLits.Printf.Internal.FormatType "v" GHC.Types.Float instance GHC.TypeLits.Printf.Internal.FormatType "v" GHC.Base.String instance GHC.TypeLits.Printf.Internal.FormatType "v" Data.Text.Internal.Text instance GHC.TypeLits.Printf.Internal.FormatType "v" Data.Text.Internal.Lazy.Text -- | An extensible and type-safe printf from parsing GHC TypeLits Symbol -- literals, matching the semantics of printf from -- 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 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 following table summarizes the features and drawbacks of each -- method: -- -- TODO: table -- -- 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! -- -- 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 -- | Typeclass associating format types (d, f, etc.) with -- the types that can be formatted by them. -- -- You can extend the printf methods here for your own types by writing -- your instances here. class FormatType (t :: SChar) a formatArg :: FormatType t a => p t -> a -> FieldFormat -> ShowS formatArg :: (FormatType t a, PrintfArg a) => p t -> a -> FieldFormat -> ShowS -- | A type synonym for a single-character symbol. Ideally this would just -- be Char, but we don't have chars at the type level. So, if you -- see SChar in a type signature, it means that it's expected to -- be a symbol/string with only one single character. type SChar = Symbol -- | Type-safe printf with true naked polyarity. Call it like -- printf @"you have %.02f dollars, %s". -- --
--   >>> putStrLn $ printf @"You have %.2f dollars, %s" 3.62 "Luigi"
--   You have 3.62 dollars, Luigi
--   
-- -- 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: -- --
--   >>> 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.
--   
-- -- If you're having problems getting the error messages to give helpful -- feedback, try using pHelp: -- --
--   >>> 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 returning strict Text and lazy Text as well. printf :: forall str fun. Printf str fun => fun -- | A version of printf taking an explicit proxy, which allows -- usage without TypeApplications -- --
--   >>> putStrLn $ printf_ (Proxy :: Proxy "You have %.2f dollars, %s") 3.62 "Luigi"
--   You have 3.62 dollars, Luigi
--   
printf_ :: Printf str fun => p str -> fun -- | A useful token for helping the type system give useful errors for -- 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. -- -- See also pHelp data PHelp -- | A useful helper function for helping the type system give useful -- errors for printf: -- --
--   >>> 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.
--   
-- -- Usually things would work out on their own without needing this ... -- but sometimes the type system could need a nudge. pHelp :: PHelp -> String -- | The typeclass supporting polyarity used by printf. It works in -- mostly the same way as PrintfType from Text.Printf, and -- similar the same as 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 -- 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
--   
-- -- 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 Text lazy 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.
--   
-- -- If you're having problems getting the error messages to give helpful -- feedback, try using pHelp: -- --
--   >>> 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 -- | 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. -- -- To give pprintf its arguments, however, they must be wrapped in -- PP: -- --
--   >>> putStrLn $ pprintf @"You have %.2f dollars, %s" (PP 3.62) (PP "Luigi")
--   You have 3.62 dollars, Luigi
--   
-- -- 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 -- | 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 -- | Required wrapper around inputs to pprintf (guarded polyarity). -- See documentation for 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) PP :: a -> PP (c :: SChar) -- | 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: -- --
--   >>> putStrLn $ rprintf @"You have %.2f dollars, %s" (3.62 ':%' "Luigi" :% 'RNil')
--   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 -- | A version of rprintf taking an explicit proxy, which allows -- usage without TypeApplications -- --
--   >>> :t rprintf_ (Proxy :: Proxy "You have %.2f dollars, %s")
--   FormatArgs '["f", "s"] -> String
--   
rprintf_ :: RPrintf str ps => p str -> FormatArgs ps -> String -- | A record is parameterized by a universe u, an interpretation -- f and a list of rows rs. The labels or indices of -- the record are given by inhabitants of the kind u; the type -- of values at any label r :: u is given by its interpretation -- f r :: *. data Rec (a :: u -> Type) (b :: [u]) [RNil] :: forall u (a :: u -> Type). Rec a ('[] :: [u]) -- | 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) infixr 7 :% -- | A heterogeneous list (from Data.Vinyl.Core) used for calling -- with rprintf. Instead of supplying the inputs as different -- arguments, we can gather all the inputs into a single list to give to -- 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 :% 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 -- | Parse and run a single format hole on a single vale. Can be -- useful for formatting individual items or for testing your own custom -- instances of FormatType. -- -- Usually meant to be used with OverloadedLabels: -- --
--   >>> pfmt #f 3.62
--   "3.62"
--   
-- -- However, current versions of GHC disallow labels that aren't valid -- identifier names, disallowing things like pfmt #.2f -- 3.62. While there is an -- <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0170-unrestricted-overloadedlabels.rst -- approved proposal> that allows this, if you are using an earlier -- GHC version, you can get around this using mkPFmt: -- --
--   >>> pfmt (mkPFmt @".2f") 3.6234124
--   "3.62"
--   
-- -- Ideally we'd want to be able to write -- --
--   >>> pfmt #.2f 3.6234124
--   "3.62"
--   
-- -- (which should be possible in GHC 8.10+) -- -- Note that the format string does not include the leading %. pfmt :: forall c a. FormatType c a => PFmt c -> a -> String -- | Utility type powering pfmt. See dcumentation for pfmt -- for more information on usage. -- -- Using OverloadedLabels, you never need to construct this -- directly can just write #f and a PFmt "f" -- will be generated. You can also create this using mkPFmt or -- mkPFmt_, in the situations where OverloadedLabels -- doesn't work or is not wanted. data PFmt c -- | Useful for using pfmt without OverloadedLabels, or also -- when passing format specifiers that aren't currently allowed with -- OverloadedLabels until GHC 8.10+ (like #.2f). -- --
--   >>> pfmt (mkPFmt @".2f") 3.6234124
--   "3.62"
--   
mkPFmt :: forall str lst ff f w q m c. (Listify str lst, ff ~ ParseFmt_ lst, Reflect ff, ff ~ 'FF f w q m c) => PFmt c -- | A version of mkPFmt that takes an explicit proxy input. -- --
--   >>> 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) => p str -> PFmt c