Added Turtle.Format

This commit is contained in:
Gabriel Gonzalez 2015-01-19 21:21:34 -08:00
parent 34ae7016f8
commit e29df632c4
3 changed files with 112 additions and 1 deletions

View file

@ -8,6 +8,8 @@
-- This module re-exports the rest of the library and also re-exports useful
-- modules from @base@:
--
-- "Turtle.Format" provides type-safe string formatting
--
-- "Turtle.Pattern" provides `Pattern`s, which are like more powerful regular
-- expressions
--
@ -61,7 +63,8 @@
module Turtle (
-- * Modules
module Turtle.Pattern
module Turtle.Format
, module Turtle.Pattern
, module Turtle.Protected
, module Turtle.Shell
, module Turtle.Prelude
@ -77,6 +80,7 @@ module Turtle (
, ExitCode(..)
) where
import Turtle.Format
import Turtle.Pattern
import Turtle.Protected
import Turtle.Shell

106
src/Turtle/Format.hs Normal file
View file

@ -0,0 +1,106 @@
{-# LANGUAGE OverloadedStrings #-}
{-| Minimalist implementation of type-safe formatted strings, borrowing heavily
from the implementation of the @formatting@ package.
Example use of this module:
>>> :set -XOverloadedStrings
>>> import Turtle
>>> 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
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
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
-}
{-# LANGUAGE TypeFamilies #-}
module Turtle.Format (
-- * Format
Format
, (%)
, format
, makeFormat
-- * Parameters
, w
, d
, u
, f
, s
) where
import Control.Category (Category(..))
import Data.Monoid ((<>))
import Data.String (IsString(..))
import Data.Text (Text, pack)
import Data.Word (Word)
import Prelude hiding ((.), id, FilePath)
-- | A `Format` string
newtype Format a b = Format { (>>-) :: (Text -> a) -> b }
instance Category Format where
id = Format (\return_ -> return_ "")
fmt1 . fmt2 = Format (\return_ ->
fmt1 >>- \str1 ->
fmt2 >>- \str2 ->
return_ (str1 <> str2) )
-- | Concatenate two `Format` strings
(%) :: Format b c -> Format a b -> Format a c
(%) = (.)
instance (a ~ b) => IsString (Format a b) where
fromString str = Format (\return_ -> return_ (pack str))
{-| Convert a `Format` string to a print function that takes zero or more typed
arguments and returns a `Text` string
-}
format :: Format Text r -> r
format fmt = fmt >>- id
-- | Create your own format specifier
makeFormat :: (a -> Text) -> Format r (a -> r)
makeFormat k = Format (\return_ -> \a -> return_ (k a))
-- | `Format` string that inserts any `Show`able value
w :: Show a => Format r (a -> r)
w = makeFormat (pack . show)
-- | `Format` string that inserts an `Int` value
d :: Format r (Int -> r)
d = w
-- | `Format` string that inserts a `Word` value
u :: Format r (Word -> r)
u = w
-- | `Format` string that inserts a `Double`
f :: Format r (Double -> r)
f = w
-- | `Format` string that inserts `Text`
s :: Format r (Text -> r)
s = makeFormat id

View file

@ -50,6 +50,7 @@ Library
Build-Depends: unix >= 2.5.1.0 && < 2.8
Exposed-Modules:
Turtle,
Turtle.Format,
Turtle.Pattern,
Turtle.Protected,
Turtle.Shell,