Added more format specifiers

This commit is contained in:
Gabriel Gonzalez 2015-01-19 21:52:51 -08:00
parent e29df632c4
commit e73580890d
2 changed files with 83 additions and 15 deletions

View file

@ -6,31 +6,34 @@
Example use of this module: Example use of this module:
>>> :set -XOverloadedStrings >>> :set -XOverloadedStrings
>>> import Turtle >>> import Turtle.Format
>>> format ("This is a "%s%" string that takes "%d%" arguments") "format" 2 >>> format ("This is a "%s%" string that takes "%d%" arguments") "format" 2
"This is a format string that takes 2 arguments" "This is a format string that takes 2 arguments"
A `Format` string that takes no arguments has this type: A `Format` string that takes no arguments has this type:
> "I take 0 arguments" :: Format r r > "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: A `Format` string that takes one argument has this type:
> "I take "%d%" arguments" :: Format r (Int -> r) > "I take "%d%" arguments" :: Format r (Int -> r)
> >
> format ("I take "%d%" argument") :: Int -> Text > 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: A `Format` string that takes two arguments has this type:
> "I "%s%" "%d%" arguments" :: Format r (Text -> Int -> r) > "I "%s%" "%d%" arguments" :: Format r (Text -> Int -> r)
> >
> format ("I "%s%" "%d%" arguments") :: Text -> Int -> Text > 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 #-} {-# LANGUAGE TypeFamilies #-}
@ -46,7 +49,11 @@ module Turtle.Format (
, w , w
, d , d
, u , u
, o
, x
, f , f
, e
, g
, s , s
) where ) where
@ -55,6 +62,7 @@ import Data.Monoid ((<>))
import Data.String (IsString(..)) import Data.String (IsString(..))
import Data.Text (Text, pack) import Data.Text (Text, pack)
import Data.Word (Word) import Data.Word (Word)
import Numeric (showEFloat, showFFloat, showGFloat, showHex, showOct)
import Prelude hiding ((.), id, FilePath) import Prelude hiding ((.), id, FilePath)
-- | A `Format` string -- | A `Format` string
@ -85,22 +93,82 @@ format fmt = fmt >>- id
makeFormat :: (a -> Text) -> Format r (a -> r) makeFormat :: (a -> Text) -> Format r (a -> r)
makeFormat k = Format (\return_ -> \a -> return_ (k a)) 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 :: Show a => Format r (a -> r)
w = makeFormat (pack . show) 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 :: Format r (Int -> r)
d = w 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 :: Format r (Word -> r)
u = w u = w
-- | `Format` string that inserts a `Double` {-| `Format` a `Word` value as an unsigned octal number
f :: Format r (Double -> r)
f = w
-- | `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 :: Format r (Text -> r)
s = makeFormat id s = makeFormat id

View file

@ -3,4 +3,4 @@ module Main where
import Test.DocTest import Test.DocTest
main :: IO () main :: IO ()
main = doctest ["src/Turtle/Pattern.hs"] main = doctest ["src/Turtle/Pattern.hs", "src/Turtle/Format.hs"]