-- 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.2.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 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 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). -- -- 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. --class FormatFun (ffs :: [Either Symbol FieldFormat]) fun formatFun :: FormatFun ffs fun => p ffs -> String -> fun -- | Utility type powering pfmt. See documentation 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 should 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 tool 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. ---- -- Mostly useful if you want to force a useful type error to help see -- what is going on. -- -- 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. ---- -- Mostly useful if you want to force a useful type error to help see -- what is going on. [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.Base.String) => 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 (afun GHC.Types.~ (arg -> fun), 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 arg, GHC.TypeLits.Printf.Internal.FormatFun ffs fun) => GHC.TypeLits.Printf.Internal.FormatFun ('Data.Either.Right ff : ffs) afun 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 your -- printfs 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. See documentation in Text.Printf for details -- on how this formats items of various types, and the differences with C -- printf(3). -- -- See printf for the main function. -- -- 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 -- | "Type-safe printf". 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 ---- -- Looking at its type: -- --
-- >>> :t printf @"You have %.2f dollars, %s" -- (FormatType "f" arg1, FormatType "s" arg2) -- => arg1 -> arg2 -> String ---- -- 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). -- -- We can see this in action by progressively applying arguments: -- --
-- >>> :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 ---- -- The type errors for forgetting to apply an argument (or applying too -- many arguments) are pretty clear: -- --
-- >>> 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. -- -- >>> 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. -- -- >>> putStrLn $ printf @"You have %.2f dollars, %s" 3.62 "Luigi" -- You have 3.62 dollars, Luigi -- -- >>> 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 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. ---- -- 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 tool 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. ---- -- Mostly useful if you want to force a useful type error to help see -- what is going on. -- -- 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. ---- -- Mostly useful if you want to force a useful type error to help see -- what is going on. 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 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). -- -- 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. --class FormatFun (ffs :: [Either Symbol FieldFormat]) fun -- | 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 -- | 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 should not include the leading %. pfmt :: forall c a. FormatType c a => PFmt c -> a -> String -- | Utility type powering pfmt. See documentation 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