diff --git a/src/Turtle/Format.hs b/src/Turtle/Format.hs index f200e00..9485d62 100644 --- a/src/Turtle/Format.hs +++ b/src/Turtle/Format.hs @@ -6,31 +6,34 @@ Example use of this module: >>> :set -XOverloadedStrings ->>> import Turtle +>>> import Turtle.Format >>> format ("This is a "%s%" string that takes "%d%" arguments") "format" 2 "This is a format string that takes 2 arguments" A `Format` string that takes no arguments has this type: > "I take 0 arguments" :: Format r r -> -> format "I take 0 arguments" :: Text + +>>> format "I take 0 arguments" :: Text +"I take 0 arguments" A `Format` string that takes one argument has this type: > "I take "%d%" arguments" :: Format r (Int -> r) > > format ("I take "%d%" argument") :: Int -> Text -> -> format ("I take "%d%" argument") 1 :: Text + +>>> format ("I take "%d%" argument") 1 :: Text +"I take 1 argument" A `Format` string that takes two arguments has this type: > "I "%s%" "%d%" arguments" :: Format r (Text -> Int -> r) > > format ("I "%s%" "%d%" arguments") :: Text -> Int -> Text -> -> format ("I "%s%" "%d%" arguments") "take" 2 :: Text + +>>> format ("I "%s%" "%d%" arguments") "take" 2 :: Text +"I take 2 arguments" -} {-# LANGUAGE TypeFamilies #-} @@ -46,7 +49,11 @@ module Turtle.Format ( , w , d , u + , o + , x , f + , e + , g , s ) where @@ -55,6 +62,7 @@ import Data.Monoid ((<>)) import Data.String (IsString(..)) import Data.Text (Text, pack) import Data.Word (Word) +import Numeric (showEFloat, showFFloat, showGFloat, showHex, showOct) import Prelude hiding ((.), id, FilePath) -- | A `Format` string @@ -85,22 +93,82 @@ format fmt = fmt >>- id makeFormat :: (a -> Text) -> Format r (a -> r) makeFormat k = Format (\return_ -> \a -> return_ (k a)) --- | `Format` string that inserts any `Show`able value +{-| `Format` any `Show`able value + +>>> format w True +"True" +-} w :: Show a => Format r (a -> r) w = makeFormat (pack . show) --- | `Format` string that inserts an `Int` value +{-| `Format` an `Int` value as a signed decimal + +>>> format d 25 +"25" +>>> format d (-25) +"-25" +-} d :: Format r (Int -> r) d = w --- | `Format` string that inserts a `Word` value +{-| `Format` a `Word` value as an unsigned decimal + +>>> format u 25 +"25" +-} u :: Format r (Word -> r) u = w --- | `Format` string that inserts a `Double` -f :: Format r (Double -> r) -f = w +{-| `Format` a `Word` value as an unsigned octal number --- | `Format` string that inserts `Text` +>>> format o 25 +"31" +-} +o :: Format r (Word -> r) +o = makeFormat (\n -> pack (showOct n "")) + +{-| `Format` a `Word` value as an unsigned hexadecimal number (without a + leading \"0x\") + +>>> format x 25 +"19" +-} +x :: Format r (Word -> r) +x = makeFormat (\n -> pack (showHex n "")) + +{-| `Format` a `Double` using decimal notation with 6 digits of precision + +>>> format f 25.1 +"25.100000" +-} +f :: Format r (Double -> r) +f = makeFormat (\n -> pack (showFFloat (Just 6) n "")) + +{-| `Format` a `Double` using scientific notation with 6 digits of precision + +>>> format e 25.1 +"2.510000e1" +-} +e :: Format r (Double -> r) +e = makeFormat (\n -> pack (showEFloat (Just 6) n "")) + +{-| `Format` a `Double` using decimal notation for small exponents and + scientific notation for large exponents + +>>> format g 25.1 +"25.100000" +>>> format g 123456789 +"1.234568e8" +>>> format g 0.00000000001 +"1.000000e-11" +-} +g :: Format r (Double -> r) +g = makeFormat (\n -> pack (showGFloat (Just 6) n "")) + +{-| `Format` that inserts `Text` + +>>> format s "ABC" +"ABC" +-} s :: Format r (Text -> r) s = makeFormat id diff --git a/test/Main.hs b/test/Main.hs index 007c3da..8d4740a 100644 --- a/test/Main.hs +++ b/test/Main.hs @@ -3,4 +3,4 @@ module Main where import Test.DocTest main :: IO () -main = doctest ["src/Turtle/Pattern.hs"] +main = doctest ["src/Turtle/Pattern.hs", "src/Turtle/Format.hs"]