-- 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