-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Highbrow approach to type-safe printf format specifications. -- -- We use the co-Kleisli category for the comonad of functions out of a -- fixed monoid to implement a generic combinator library for type-safe -- format specifications. Works with pretty much anything that's a -- monoid, with specific support for String, Text (strict/lazy), and -- ByteString (strict/lazy). Credit to Daniel Patterson for introducing -- me to something that looked just enough like it ought to be the -- composition for a category, and Ryan Trinkle for the IsString -- instance. :) @package category-printf @version 0.1.1.0 module Control.Category.Printf -- | Handy type synonym for the things we're working with. You should -- regard a value of type Format m a b as something which -- explains how to write some element of the monoid m (a -- "string" for our purposes), and which will change the type of printf -- from a to b. For instance, something which adds a -- responsibility to provide an additional argument of type t -- might have type Format m a (t -> a), while a formatter -- which somehow absolves you of that responsibility would have type -- Format m (t -> a) a. type Format m = Cokleisli ((->) m) -- | We can apply this to something like putStrLn to get a function for -- formatted printing. Typically you'll have r = IO (), but that -- needn't be the case. printfWith :: (m -> r) -> Format m r b -> b -- | If you just want to build a string / element of your monoid, we have -- sprintf = printfWith id sprintf :: Format m m b -> b -- | Formatter for a constant string. Note that for string literals, this -- is implicit if you turn on the OverloadedStrings extension. -- --
--   >>> let x = "world" in printfLn (c "Hello, " . c x . c "!")
--   Hello, world!
--   
c :: (Monoid m) => m -> Format m a a -- | Inclusion of a string as an argument. -- --
--   >>> mapM_ (printfLn ("Hello, " . i . "!")) ["Anne", "Bob", "world"]
--   Hello, Anne!
--   Hello, Bob!
--   Hello, world!
--   
i :: Format m a (m -> a) -- | Given a way to turn a value of type t into a string, this builds a -- formatter which demands an additional argument of type t and splices -- it in. spliceWith :: (Monoid m) => (t -> m) -> Format m a (t -> a) -- | Splice in anything showable. -- --
--   >>> printfLn ("list: " . s . "  tuple: " . s . "  string: " . s) [1,2,3] ("hello", 'a') "there"
--   list: [1,2,3]  tuple: ("hello",'a')  string: "there"
--   
s :: (Monoid s, IsString s, Show t) => Format s a (t -> a) -- | Select which formatter to apply based on an argument. -- --
--   >>> printfLn (bind (\b -> if b then eFloat Nothing else fFloat Nothing)) False 5328
--   5328.0
--   
-- --
--   >>> printfLn (bind (\b -> if b then eFloat Nothing else fFloat Nothing)) True 5328
--   5.328e3
--   
-- --
--   >>> printfLn (bind (\f -> f Nothing)) eFloat 5328
--   5.328e3
--   
bind :: (t -> Format s a b) -> Format s a (t -> b) -- | Apply a function to the output of a formatter, possibly changing its -- type. -- --
--   >>> printfLn (mapMonoid (map toUpper) hex) 0xcafe1234
--   CAFE1234
--   
mapMonoid :: (m -> m') -> Format m a b -> Format m' a b -- | Generalizes the string type that a formatter uses by applying -- fromString internally. generalizeString :: (IsString s, Monoid s) => Format String a b -> Format s a b -- | Transform a numeric formatter which will be used to handle absolute -- values, applying the first given function to the string to be spliced -- when the argument is negative, and the second given function -- otherwise. -- --
--   >>> printfLn (signedWith (\v -> mconcat ["(",v,")"]) id (fFloat (Just 2))) (-pi)
--   (3.14)
--   
-- --
--   >>> printfLn (signedWith ("-"<>) ("+"<>) (padLeft "0" 5 s)) (-439)
--   -00439
--   
-- --
--   >>> printfLn (signedWith ("-"<>) ("+"<>) (padLeft "0" 5 s)) 1278
--   +01278
--   
signedWith :: (Num t, Ord t, Monoid s) => (s -> s) -> (s -> s) -> Format s a (t -> b) -> Format s a (t -> b) -- | Show an integral value using the given base, and using the provided -- function to determine how to display individual digits. intAtBase :: (Real t, Integral t, Show t, Monoid s, IsString s) => t -> (Int -> Char) -> Format s a (t -> a) -- | Show an integral value in hexadecimal. -- --
--   >>> printfLn (dup . s . " in hexadecimal is " . hex) 51966
--   51966 in hexadecimal is cafe
--   
hex :: (Integral t, Show t, Monoid s, IsString s) => Format s a (t -> a) -- | Show an integral value in octal. oct :: (Integral t, Show t, Monoid s, IsString s) => Format s a (t -> a) -- | Show a floating point value in exponential format. (e.g. 2.45e2, -- -1.5e-3) If digs is Nothing, the value is shown to full -- precision, if it is Just d then at most d digits after the decimal -- point are shown. eFloat :: (RealFloat t, Monoid s, IsString s) => Maybe Int -> Format s a (t -> a) -- | Show a floating point value in standard decimal format. (e.g. 245000, -- -0.0015) If digs is Nothing, the value is shown to full -- precision, if it is Just d then at most d digits after the decimal -- point are shown. fFloat :: (RealFloat t, Monoid s, IsString s) => Maybe Int -> Format s a (t -> a) -- | Show a floating point value using standard decimal notation for -- arguments whose absolute value lies between 0.1 and 9,999,999, and -- scientific notation otherwise. If digs is Nothing, the value -- is shown to full precision, if it is Just d then at most d digits -- after the decimal point are shown. gFloat :: (RealFloat t, Monoid s, IsString s) => Maybe Int -> Format s a (t -> a) -- | We can use arr from the Arrow instance for Cokleisli w to -- produce formatters that manipulate the stack without printing. That -- is, we have -- --
--   arr :: (Monoid m) => (s -> s') -> Format m s s'
--   
-- -- Push an argument onto the stack to be consumed by subsequent -- formatters. push :: Monoid m => t -> Format m (t -> a) a -- | Duplicate an argument on the stack, making it available twice. dup :: Monoid m => Format m (t -> t -> a) (t -> a) -- | Swap the next two arguments on the stack. swap :: Monoid m => Format m (t -> t' -> a) (t' -> t -> a) -- | Skip the next argument on the stack. skip :: Monoid m => Format m a (t -> a) -- | Apply a function to the argument on the top of the stack. apply :: Monoid m => (u -> v) -> Format m (v -> a) (u -> a) -- | Apply a binary function to the top two arguments on the stack. -- --
--   >>> printfLn (dup . s . " plus " . swap . dup . s . " equals " . apply2 (+) . s) 4 6
--   4 plus 6 equals 10
--   
--   >>> printfLn (arr (\k x y -> k x y (x+y)) . s . " plus " . s . " equals " . s) 4 6
--   4 plus 6 equals 10
--   
apply2 :: Monoid m => (u -> v -> w) -> Format m (w -> a) (u -> v -> a) instance (a ~ b, IsString s, Monoid s) => IsString (Cokleisli ((->) s) a b) module Control.Category.Printf.String printf :: Format String (IO ()) b -> b printfLn :: Format String (IO ()) b -> b hPrintf :: Handle -> Format String (IO ()) b -> b hPrintfLn :: Handle -> Format String (IO ()) b -> b -- | padLeft s n f will transform the formatter f, ensuring that the output -- produced is at least length n by appending sufficiently many copies of -- s on the left. The string s should have length at least 1, otherwise -- this has no effect. In cases where s has length greater than 1, the -- last occurrence of s will be truncated as necessary to fit the -- necessary width. padLeft :: String -> Int -> Format String a b -> Format String a b -- | padRight s n f will transform the formatter f, ensuring that the -- output produced is at least length n by appending sufficiently many -- copies of s on the right. The string s should have length at least 1, -- otherwise this has no effect. In cases where s has length greater than -- 1, the last occurrence of s will be truncated as necessary to fit the -- necessary width. padRight :: String -> Int -> Format String a b -> Format String a b module Control.Category.Printf.Text.Strict printf :: Format Text (IO ()) b -> b printfLn :: Format Text (IO ()) b -> b hPrintf :: Handle -> Format Text (IO ()) b -> b hPrintfLn :: Handle -> Format Text (IO ()) b -> b -- | padLeft s n f will transform the formatter f, ensuring that the output -- produced is at least length n by appending sufficiently many copies of -- s on the left. The string s should have length at least 1, otherwise -- this has no effect. In cases where s has length greater than 1, the -- last occurrence of s will be truncated as necessary to fit the -- necessary width. padLeft :: Text -> Int -> Format Text a b -> Format Text a b -- | padRight s n f will transform the formatter f, ensuring that the -- output produced is at least length n by appending sufficiently many -- copies of s on the right. The string s should have length at least 1, -- otherwise this has no effect. In cases where s has length greater than -- 1, the last occurrence of s will be truncated as necessary to fit the -- necessary width. padRight :: Text -> Int -> Format Text a b -> Format Text a b module Control.Category.Printf.Text.Lazy printf :: Format Text (IO ()) b -> b printfLn :: Format Text (IO ()) b -> b hPrintf :: Handle -> Format Text (IO ()) b -> b hPrintfLn :: Handle -> Format Text (IO ()) b -> b -- | padLeft s n f will transform the formatter f, ensuring that the output -- produced is at least length n by appending sufficiently many copies of -- s on the left. The string s should have length at least 1, otherwise -- this has no effect. In cases where s has length greater than 1, the -- last occurrence of s will be truncated as necessary to fit the -- necessary width. padLeft :: Text -> Int64 -> Format Text a b -> Format Text a b -- | padRight s n f will transform the formatter f, ensuring that the -- output produced is at least length n by appending sufficiently many -- copies of s on the right. The string s should have length at least 1, -- otherwise this has no effect. In cases where s has length greater than -- 1, the last occurrence of s will be truncated as necessary to fit the -- necessary width. padRight :: Text -> Int64 -> Format Text a b -> Format Text a b module Control.Category.Printf.ByteString.Strict printf :: Format ByteString (IO ()) b -> b printfLn :: Format ByteString (IO ()) b -> b hPrintf :: Handle -> Format ByteString (IO ()) b -> b hPrintfLn :: Handle -> Format ByteString (IO ()) b -> b -- | padLeft s n f will transform the formatter f, ensuring that the output -- produced is at least length n by appending sufficiently many copies of -- s on the left. The string s should have length at least 1, otherwise -- this has no effect. In cases where s has length greater than 1, the -- last occurrence of s will be truncated as necessary to fit the -- necessary width. padLeft :: ByteString -> Int -> Format ByteString a b -> Format ByteString a b -- | padRight s n f will transform the formatter f, ensuring that the -- output produced is at least length n by appending sufficiently many -- copies of s on the right. The string s should have length at least 1, -- otherwise this has no effect. In cases where s has length greater than -- 1, the last occurrence of s will be truncated as necessary to fit the -- necessary width. padRight :: ByteString -> Int -> Format ByteString a b -> Format ByteString a b module Control.Category.Printf.ByteString.Lazy printf :: Format ByteString (IO ()) b -> b printfLn :: Format ByteString (IO ()) b -> b hPrintf :: Handle -> Format ByteString (IO ()) b -> b hPrintfLn :: Handle -> Format ByteString (IO ()) b -> b -- | padLeft s n f will transform the formatter f, ensuring that the output -- produced is at least length n by appending sufficiently many copies of -- s on the left. The string s should have length at least 1, otherwise -- this has no effect. In cases where s has length greater than 1, the -- last occurrence of s will be truncated as necessary to fit the -- necessary width. padLeft :: ByteString -> Int64 -> Format ByteString a b -> Format ByteString a b -- | padRight s n f will transform the formatter f, ensuring that the -- output produced is at least length n by appending sufficiently many -- copies of s on the right. The string s should have length at least 1, -- otherwise this has no effect. In cases where s has length greater than -- 1, the last occurrence of s will be truncated as necessary to fit the -- necessary width. padRight :: ByteString -> Int64 -> Format ByteString a b -> Format ByteString a b