-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Shell programming, Haskell-style -- @package turtle @version 1.2.1 -- | You can think of Shell as [] + IO + -- Managed. In fact, you can embed all three of them within a -- Shell: -- --
--   select ::        [a] -> Shell a
--   liftIO ::      IO a  -> Shell a
--   using  :: Managed a  -> Shell a
--   
-- -- Those three embeddings obey these laws: -- --
--   do { x <- select m; select (f x) } = select (do { x <- m; f x })
--   do { x <- liftIO m; liftIO (f x) } = liftIO (do { x <- m; f x })
--   do { x <- with   m; using  (f x) } = using  (do { x <- m; f x })
--   
--   select (return x) = return x
--   liftIO (return x) = return x
--   using  (return x) = return x
--   
-- -- ... and select obeys these additional laws: -- --
--   select xs <|> select ys = select (xs <|> ys)
--   select empty = empty
--   
-- -- You typically won't build Shells using the Shell -- constructor. Instead, use these functions to generate primitive -- Shells: -- -- -- --
--   -- For every shell `s`:
--   _foldIO s (FoldM step begin done) = do
--       x  <- begin
--       x' <- _foldIO s (FoldM step (return x) return)
--       done x'
--   
-- -- ... which is a fancy way of saying that your Shell must call -- 'begin' exactly once when it begins and call 'done' -- exactly once when it ends. module Turtle.Shell -- | A (Shell a) is a protected stream of a's with side -- effects newtype Shell a Shell :: (forall r. FoldM IO a r -> IO r) -> Shell a _foldIO :: Shell a -> forall r. FoldM IO a r -> IO r -- | Use a FoldM IO to reduce the stream of -- a's produced by a Shell foldIO :: MonadIO io => Shell a -> FoldM IO a r -> io r -- | Use a Fold to reduce the stream of a's produced by a -- Shell fold :: MonadIO io => Shell a -> Fold a b -> io b -- | Run a Shell to completion, discarding any unused values sh :: MonadIO io => Shell a -> io () -- | Run a Shell to completion, printing any unused values view :: (MonadIO io, Show a) => Shell a -> io () -- | Convert a list to a Shell that emits each element of the list select :: [a] -> Shell a -- | Lift a computation from the IO monad. liftIO :: MonadIO m => forall a. IO a -> m a -- | Acquire a Managed resource within a Shell in an -- exception-safe way using :: Managed a -> Shell a instance IsString a => IsString (Shell a) instance Monoid a => Num (Shell a) instance Monoid a => Monoid (Shell a) instance MonadIO Shell instance MonadPlus Shell instance Alternative Shell instance Monad Shell instance Applicative Shell instance Functor Shell -- | Example usage of this module: -- --
--   -- options.hs
--   
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import Turtle
--   
--   parser :: Parser (Text, Int)
--   parser = (,) <$> optText "name" 'n' "Your first name"
--                <*> optInt  "age"  'a' "Your current age"
--   
--   main = do
--       (name, age) <- options "Greeting script" parser
--       echo (format ("Hello there, "%s) name)
--       echo (format ("You are "%d%" years old") age)
--   
-- --
--   $ ./options --name John --age 42
--   Hello there, John
--   You are 42 years old
--   
-- --
--   $ ./options --help
--   Greeting script
--   
--   Usage: options (-n|--name NAME) (-a|--age AGE)
--   
--   Available options:
--    -h,--help                Show this help text
--    --name NAME              Your first name
--    --age AGE                Your current age
--   
module Turtle.Options -- | A Parser a is an option parser returning a value of type -- a. data Parser a :: * -> * -- | The name of a command-line argument -- -- This is used to infer the long name and metavariable for the command -- line flag. For example, an ArgName of "name" will -- create a --name flag with a NAME metavariable data ArgName -- | The short one-character abbreviation for a flag (i.e. -n) type ShortName = Char -- | A brief description of what your program does -- -- This description will appear in the header of the --help -- output data Description -- | A helpful message explaining what a flag does -- -- This will appear in the --help output data HelpMessage -- | This parser returns True if the given flag is set and -- False if the flag is absent switch :: ArgName -> ShortName -> Optional HelpMessage -> Parser Bool -- | Parse a Text value as a flag-based option optText :: ArgName -> ShortName -> Optional HelpMessage -> Parser Text -- | Parse an Int as a flag-based option optInt :: ArgName -> ShortName -> Optional HelpMessage -> Parser Int -- | Parse an Integer as a flag-based option optInteger :: ArgName -> ShortName -> Optional HelpMessage -> Parser Integer -- | Parse a Double as a flag-based option optDouble :: ArgName -> ShortName -> Optional HelpMessage -> Parser Double -- | Parse a FilePath value as a flag-based option optPath :: ArgName -> ShortName -> Optional HelpMessage -> Parser FilePath -- | Parse any type that implements Read optRead :: Read a => ArgName -> ShortName -> Optional HelpMessage -> Parser a -- | Build a flag-based option parser for any type by providing a -- Text-parsing function opt :: (Text -> Maybe a) -> ArgName -> ShortName -> Optional HelpMessage -> Parser a -- | Parse a Text as a positional argument argText :: ArgName -> Optional HelpMessage -> Parser Text -- | Parse an Int as a positional argument argInt :: ArgName -> Optional HelpMessage -> Parser Int -- | Parse an Integer as a positional argument argInteger :: ArgName -> Optional HelpMessage -> Parser Integer -- | Parse a Double as a positional argument argDouble :: ArgName -> Optional HelpMessage -> Parser Double -- | Parse a FilePath as a positional argument argPath :: ArgName -> Optional HelpMessage -> Parser FilePath -- | Parse any type that implements Read as a positional argument argRead :: Read a => ArgName -> Optional HelpMessage -> Parser a -- | Build a positional argument parser for any type by providing a -- Text-parsing function arg :: (Text -> Maybe a) -> ArgName -> Optional HelpMessage -> Parser a -- | Parse the given options from the command line options :: MonadIO io => Description -> Parser a -> io a instance IsString ArgName instance IsString Description instance IsString HelpMessage -- | Use this module to either: -- -- -- --
--   >>> :set -XOverloadedStrings
--   
--   >>> match ("can" <|> "cat") "cat"
--   ["cat"]
--   
--   >>> match ("can" <|> "cat") "dog"
--   []
--   
--   >>> match (decimal `sepBy` ",") "1,2,3"
--   [[1,2,3]]
--   
-- -- This pattern has unlimited backtracking, and will return as many -- solutions as possible: -- --
--   >>> match (prefix (star anyChar)) "123"
--   ["123","12","1",""]
--   
-- -- Use do notation to structure more complex patterns: -- --
--   >>> :{
--   let bit = ("0" *> pure False) <|> ("1" *> pure True) :: Pattern Bool;
--       portableBitMap = do
--           { "P1"
--           ; width  <- spaces1 *> decimal
--           ; height <- spaces1 *> decimal
--           ; count width (count height (spaces1 *> bit))
--           };
--   in  match (prefix portableBitMap) "P1\n2 2\n0 0\n1 0\n"
--   :}
--   [[[False,False],[True,False]]]
--   
module Turtle.Pattern -- | A fully backtracking pattern that parses an 'a' from some -- Text data Pattern a -- | Match a Pattern against a Text input, returning all -- possible solutions -- -- The Pattern must match the entire Text match :: Pattern a -> Text -> [a] -- | Match any character -- --
--   >>> match anyChar "1"
--   "1"
--   
--   >>> match anyChar ""
--   ""
--   
anyChar :: Pattern Char -- | Matches the end of input -- --
--   >>> match eof "1"
--   []
--   
--   >>> match eof ""
--   [()]
--   
eof :: Pattern () -- | Synonym for anyChar dot :: Pattern Char -- | Match any character that satisfies the given predicate -- --
--   >>> match (satisfy (== '1')) "1"
--   "1"
--   
--   >>> match (satisfy (== '2')) "1"
--   ""
--   
satisfy :: (Char -> Bool) -> Pattern Char -- | Match a specific character -- --
--   >>> match (char '1') "1"
--   "1"
--   
--   >>> match (char '2') "1"
--   ""
--   
char :: Char -> Pattern Char -- | Match any character except the given one -- --
--   >>> match (notChar '2') "1"
--   "1"
--   
--   >>> match (notChar '1') "1"
--   ""
--   
notChar :: Char -> Pattern Char -- | Match a specific string -- --
--   >>> match (text "123") "123"
--   ["123"]
--   
-- -- You can also omit the text function if you enable the -- OverloadedStrings extension: -- --
--   >>> match "123" "123"
--   ["123"]
--   
text :: Text -> Pattern Text -- | Match a specific string in a case-insensitive way -- -- This only handles ASCII strings -- --
--   >>> match (asciiCI "abc") "ABC"
--   ["ABC"]
--   
asciiCI :: Text -> Pattern Text -- | Match any one of the given characters -- --
--   >>> match (oneOf "1a") "1"
--   "1"
--   
--   >>> match (oneOf "2a") "1"
--   ""
--   
oneOf :: [Char] -> Pattern Char -- | Match anything other than the given characters -- --
--   >>> match (noneOf "2a") "1"
--   "1"
--   
--   >>> match (noneOf "1a") "1"
--   ""
--   
noneOf :: [Char] -> Pattern Char -- | Match a whitespace character -- --
--   >>> match space " "
--   " "
--   
--   >>> match space "1"
--   ""
--   
space :: Pattern Char -- | Match zero or more whitespace characters -- --
--   >>> match spaces "  "
--   ["  "]
--   
--   >>> match spaces ""
--   [""]
--   
spaces :: Pattern Text -- | Match one or more whitespace characters -- --
--   >>> match spaces1 "  "
--   ["  "]
--   
--   >>> match spaces1 ""
--   []
--   
spaces1 :: Pattern Text -- | Match the tab character ('t') -- --
--   >>> match tab "\t"
--   "\t"
--   
--   >>> match tab " "
--   ""
--   
tab :: Pattern Char -- | Match the newline character ('n') -- --
--   >>> match newline "\n"
--   "\n"
--   
--   >>> match newline " "
--   ""
--   
newline :: Pattern Char -- | Matches a carriage return ('r') followed by a newline -- ('n') -- --
--   >>> match crlf "\r\n"
--   ["\r\n"]
--   
--   >>> match crlf "\n\r"
--   []
--   
crlf :: Pattern Text -- | Match an uppercase letter -- --
--   >>> match upper "A"
--   "A"
--   
--   >>> match upper "a"
--   ""
--   
upper :: Pattern Char -- | Match a lowercase letter -- --
--   >>> match lower "a"
--   "a"
--   
--   >>> match lower "A"
--   ""
--   
lower :: Pattern Char -- | Match a letter or digit -- --
--   >>> match alphaNum "1"
--   "1"
--   
--   >>> match alphaNum "a"
--   "a"
--   
--   >>> match alphaNum "A"
--   "A"
--   
--   >>> match alphaNum "."
--   ""
--   
alphaNum :: Pattern Char -- | Match a letter -- --
--   >>> match letter "A"
--   "A"
--   
--   >>> match letter "a"
--   "a"
--   
--   >>> match letter "1"
--   ""
--   
letter :: Pattern Char -- | Match a digit -- --
--   >>> match digit "1"
--   "1"
--   
--   >>> match digit "a"
--   ""
--   
digit :: Pattern Char -- | Match a hexadecimal digit -- --
--   >>> match hexDigit "1"
--   "1"
--   
--   >>> match hexDigit "A"
--   "A"
--   
--   >>> match hexDigit "a"
--   "a"
--   
--   >>> match hexDigit "g"
--   ""
--   
hexDigit :: Pattern Char -- | Match an octal digit -- --
--   >>> match octDigit "1"
--   "1"
--   
--   >>> match octDigit "9"
--   ""
--   
octDigit :: Pattern Char -- | Match an unsigned decimal number -- --
--   >>> match decimal  "123"
--   [123]
--   
--   >>> match decimal "-123"
--   []
--   
decimal :: Num n => Pattern n -- | Transform a numeric parser to accept an optional leading '+' -- or '-' sign -- --
--   >>> match (signed decimal) "+123"
--   [123]
--   
--   >>> match (signed decimal) "-123"
--   [-123]
--   
--   >>> match (signed decimal)  "123"
--   [123]
--   
signed :: Num a => Pattern a -> Pattern a -- | Use this to match the prefix of a string -- --
--   >>> match         "A"  "ABC"
--   []
--   
--   >>> match (prefix "A") "ABC"
--   ["A"]
--   
prefix :: Pattern a -> Pattern a -- | Use this to match the suffix of a string -- --
--   >>> match         "C"  "ABC"
--   []
--   
--   >>> match (suffix "C") "ABC"
--   ["C"]
--   
suffix :: Pattern a -> Pattern a -- | Use this to match the interior of a string -- --
--   >>> match      "B"  "ABC"
--   []
--   
--   >>> match (has "B") "ABC"
--   ["B"]
--   
has :: Pattern a -> Pattern a -- | (invert p) succeeds if p fails and fails if -- p succeeds -- --
--   >>> match (invert "A") "A"
--   []
--   
--   >>> match (invert "A") "B"
--   [()]
--   
invert :: Pattern a -> Pattern () -- | Match a Char, but return Text -- --
--   >>> match (once (char '1')) "1"
--   ["1"]
--   
--   >>> match (once (char '1')) ""
--   []
--   
once :: Pattern Char -> Pattern Text -- | Parse 0 or more occurrences of the given character -- --
--   >>> match (star anyChar) "123"
--   ["123"]
--   
--   >>> match (star anyChar) ""
--   [""]
--   
-- -- See also: chars star :: Pattern Char -> Pattern Text -- | Parse 1 or more occurrences of the given character -- --
--   >>> match (plus digit) "123"
--   ["123"]
--   
--   >>> match (plus digit) ""
--   []
--   
-- -- See also: chars1 plus :: Pattern Char -> Pattern Text -- | Patterns that match multiple times are greedy by default, meaning that -- they try to match as many times as possible. The selfless -- combinator makes a pattern match as few times as possible -- -- This only changes the order in which solutions are returned, by -- prioritizing less greedy solutions -- --
--   >>> match (prefix (selfless (some anyChar))) "123"
--   ["1","12","123"]
--   
--   >>> match (prefix           (some anyChar) ) "123"
--   ["123","12","1"]
--   
selfless :: Pattern a -> Pattern a -- | Apply the patterns in the list in order, until one of them succeeds -- --
--   >>> match (choice ["cat", "dog", "egg"]) "egg"
--   ["egg"]
--   
--   >>> match (choice ["cat", "dog", "egg"]) "cat"
--   ["cat"]
--   
--   >>> match (choice ["cat", "dog", "egg"]) "fan"
--   []
--   
choice :: [Pattern a] -> Pattern a -- | Apply the given pattern a fixed number of times, collecting the -- results -- --
--   >>> match (count 3 anyChar) "123"
--   ["123"]
--   
--   >>> match (count 4 anyChar) "123"
--   []
--   
count :: Int -> Pattern a -> Pattern [a] -- | Apply the given pattern 0 or more times, up to a given bound, -- collecting the results -- --
--   >>> match (upperBounded 5 dot) "123"
--   ["123"]
--   
--   >>> match (upperBounded 2 dot) "123"
--   []
--   
--   >>> match ((,) <$> upperBounded 2 dot <*> chars) "123"
--   [("12","3"),("1","23")]
--   
upperBounded :: Int -> Pattern a -> Pattern [a] -- | Apply the given pattern a number of times restricted by given lower -- and upper bounds, collecting the results -- --
--   >>> match (bounded 2 5 "cat") "catcatcat"
--   [["cat","cat","cat"]]
--   
--   >>> match (bounded 2 5 "cat") "cat"
--   []
--   
--   >>> match (bounded 2 5 "cat") "catcatcatcatcatcat"
--   []
--   
-- -- bounded could be implemented naively as follows: -- --
--   bounded m n p = do
--     x <- choice (map pure [m..n])
--     count x p
--   
bounded :: Int -> Int -> Pattern a -> Pattern [a] -- | Transform a parser to a succeed with an empty value instead of failing -- -- See also: optional -- --
--   >>> match (option "1" <> "2") "12"
--   ["12"]
--   
--   >>> match (option "1" <> "2") "2"
--   ["2"]
--   
option :: Monoid a => Pattern a -> Pattern a -- | (between open close p) matches 'p' in between -- 'open' and 'close' -- --
--   >>> match (between (char '(') (char ')') (star anyChar)) "(123)"
--   ["123"]
--   
--   >>> match (between (char '(') (char ')') (star anyChar)) "(123"
--   []
--   
between :: Pattern a -> Pattern b -> Pattern c -> Pattern c -- | Discard the pattern's result -- --
--   >>> match (skip anyChar) "1"
--   [()]
--   
--   >>> match (skip anyChar) ""
--   []
--   
skip :: Pattern a -> Pattern () -- | Restrict the pattern to consume no more than the given number of -- characters -- --
--   >>> match (within 2 decimal) "12"
--   [12]
--   
--   >>> match (within 2 decimal) "1"
--   [1]
--   
--   >>> match (within 2 decimal) "123"
--   []
--   
within :: Int -> Pattern a -> Pattern a -- | Require the pattern to consume exactly the given number of characters -- --
--   >>> match (fixed 2 decimal) "12"
--   [12]
--   
--   >>> match (fixed 2 decimal) "1"
--   []
--   
fixed :: Int -> Pattern a -> Pattern a -- | p sepBy sep matches zero or more occurrences of -- p separated by sep -- --
--   >>> match (decimal `sepBy` char ',') "1,2,3"
--   [[1,2,3]]
--   
--   >>> match (decimal `sepBy` char ',') ""
--   [[]]
--   
sepBy :: Pattern a -> Pattern b -> Pattern [a] -- | p sepBy1 sep matches one or more occurrences of -- p separated by sep -- --
--   >>> match (decimal `sepBy1` ",") "1,2,3"
--   [[1,2,3]]
--   
--   >>> match (decimal `sepBy1` ",") ""
--   []
--   
sepBy1 :: Pattern a -> Pattern b -> Pattern [a] -- | Like star dot or star anyChar, except more efficient chars :: Pattern Text -- | Like plus dot or plus anyChar, except more efficient chars1 :: Pattern Text instance Functor Pattern instance Applicative Pattern instance Monad Pattern instance Alternative Pattern instance MonadPlus Pattern instance a ~ Text => IsString (Pattern a) instance Monoid a => Num (Pattern a) instance Monoid a => Monoid (Pattern a) -- | 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
--   
--   >>> 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"
--   "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
--   "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
--   "I take 2 arguments"
--   
module Turtle.Format -- | A Format string data Format a b -- | Concatenate two Format strings (%) :: Format b c -> Format a b -> Format a c -- | 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 -- | Create your own format specifier makeFormat :: (a -> Text) -> Format r (a -> r) -- | Format any Showable value -- --
--   >>> format w True
--   "True"
--   
w :: Show a => Format r (a -> r) -- | Format an Int value as a signed decimal -- --
--   >>> format d 25
--   "25"
--   
--   >>> format d (-25)
--   "-25"
--   
d :: Format r (Int -> r) -- | Format a Word value as an unsigned decimal -- --
--   >>> format u 25
--   "25"
--   
u :: Format r (Word -> r) -- | Format a Word value as an unsigned octal number -- --
--   >>> format o 25
--   "31"
--   
o :: Format r (Word -> r) -- | Format a Word value as an unsigned hexadecimal number -- (without a leading "0x") -- --
--   >>> format x 25
--   "19"
--   
x :: Format r (Word -> r) -- | Format a Double using decimal notation with 6 digits of -- precision -- --
--   >>> format f 25.1
--   "25.100000"
--   
f :: Format r (Double -> r) -- | Format a Double using scientific notation with 6 digits -- of precision -- --
--   >>> format e 25.1
--   "2.510000e1"
--   
e :: Format r (Double -> r) -- | 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) -- | Format that inserts Text -- --
--   >>> format s "ABC"
--   "ABC"
--   
s :: Format r (Text -> r) -- | Format a FilePath into Text fp :: Format r (FilePath -> r) -- | Convert a Showable value to Text -- -- Short-hand for (format w) -- --
--   >>> repr (1,2)
--   "(1,2)"
--   
repr :: Show a => a -> Text instance a ~ b => IsString (Format a b) instance Category Format -- | This module provides a large suite of utilities that resemble Unix -- utilities. -- -- Many of these commands are just existing Haskell commands renamed to -- match their Unix counterparts: -- --
--   >>> :set -XOverloadedStrings
--   
--   >>> cd "/tmp"
--   
--   >>> pwd
--   FilePath "/tmp"
--   
-- -- Some commands are Shells that emit streams of values. -- view prints all values in a Shell stream: -- --
--   >>> view (ls "/usr")
--   FilePath "/usr/lib"
--   FilePath "/usr/src"
--   FilePath "/usr/sbin"
--   FilePath "/usr/include"
--   FilePath "/usr/share"
--   FilePath "/usr/games"
--   FilePath "/usr/local"
--   FilePath "/usr/bin"
--   
--   >>> view (find (suffix "Browser.py") "/usr/lib")
--   FilePath "/usr/lib/python3.4/idlelib/ClassBrowser.py"
--   FilePath "/usr/lib/python3.4/idlelib/RemoteObjectBrowser.py"
--   FilePath "/usr/lib/python3.4/idlelib/PathBrowser.py"
--   FilePath "/usr/lib/python3.4/idlelib/ObjectBrowser.py"
--   
-- -- Use fold to reduce the output of a Shell stream: -- --
--   >>> import qualified Control.Foldl as Fold
--   
--   >>> fold (ls "/usr") Fold.length
--   8
--   
--   >>> fold (find (suffix "Browser.py") "/usr/lib") Fold.head
--   Just (FilePath "/usr/lib/python3.4/idlelib/ClassBrowser.py")
--   
-- -- Create files using output: -- --
--   >>> output "foo.txt" ("123" <|> "456" <|> "ABC")
--   
--   >>> realpath "foo.txt"
--   FilePath "/tmp/foo.txt"
--   
-- -- Read in files using input: -- --
--   >>> stdout (input "foo.txt")
--   123
--   456
--   ABC
--   
-- -- Commands like grep, sed and find accept arbitrary -- Patterns -- --
--   >>> stdout (grep ("123" <|> "ABC") (input "foo.txt"))
--   123
--   ABC
--   
--   >>> let exclaim = fmap (<> "!") (plus digit)
--   
--   >>> stdout (sed exclaim (input "foo.txt"))
--   123!
--   456!
--   ABC
--   
-- -- Note that grep and find differ from their Unix -- counterparts by requiring that the Pattern matches the entire -- line or file name by default. However, you can optionally match the -- prefix, suffix, or interior of a line: -- --
--   >>> stdout (grep (has    "2") (input "foo.txt"))
--   123
--   
--   >>> stdout (grep (prefix "1") (input "foo.txt"))
--   123
--   
--   >>> stdout (grep (suffix "3") (input "foo.txt"))
--   123
--   
-- -- You can also build up more sophisticated Shell programs using -- sh in conjunction with do notation: -- --
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import Turtle
--   
--   main = sh example
--   
--   example = do
--       -- Read in file names from "files1.txt" and "files2.txt"
--       file <- fmap fromText (input "files1.txt" <|> input "files2.txt")
--   
--       -- Stream each file to standard output only if the file exists
--       True <- liftIO (testfile file)
--       line <- input file
--       liftIO (echo line)
--   
-- -- See Turtle.Tutorial for an extended tutorial explaining how to -- use this library in greater detail. module Turtle.Prelude -- | Run a command using execvp, retrieving the exit code -- -- The command inherits stdout and stderr for the -- current process proc :: MonadIO io => Text -> [Text] -> Shell Text -> io ExitCode -- | Run a command line using the shell, retrieving the exit code -- -- This command is more powerful than proc, but highly vulnerable -- to code injection if you template the command line with untrusted -- input -- -- The command inherits stdout and stderr for the -- current process shell :: MonadIO io => Text -> Shell Text -> io ExitCode -- | Run a command using execvp, retrieving the exit code and -- stdout as a non-lazy blob of Text -- -- The command inherits stderr for the current process procStrict :: MonadIO io => Text -> [Text] -> Shell Text -> io (ExitCode, Text) -- | Run a command line using the shell, retrieving the exit code and -- stdout as a non-lazy blob of Text -- -- This command is more powerful than proc, but highly vulnerable -- to code injection if you template the command line with untrusted -- input -- -- The command inherits stderr for the current process shellStrict :: MonadIO io => Text -> Shell Text -> io (ExitCode, Text) -- | Print to stdout echo :: MonadIO io => Text -> io () -- | Print to stderr err :: MonadIO io => Text -> io () -- | Read in a line from stdin -- -- Returns Nothing if at end of input readline :: MonadIO io => io (Maybe Text) -- | Get command line arguments in a list arguments :: MonadIO io => io [Text] -- | Set or modify an environment variable export :: MonadIO io => Text -> Text -> io () -- | Delete an environment variable unset :: MonadIO io => Text -> io () -- | Look up an environment variable need :: MonadIO io => Text -> io (Maybe Text) -- | Retrieve all environment variables env :: MonadIO io => io [(Text, Text)] -- | Change the current directory cd :: MonadIO io => FilePath -> io () -- | Get the current directory pwd :: MonadIO io => io FilePath -- | Get the home directory home :: MonadIO io => io FilePath -- | Canonicalize a path realpath :: MonadIO io => FilePath -> io FilePath -- | Move a file or directory mv :: MonadIO io => FilePath -> FilePath -> io () -- | Create a directory -- -- Fails if the directory is present mkdir :: MonadIO io => FilePath -> io () -- | Create a directory tree (equivalent to mkdir -p) -- -- Does not fail if the directory is present mktree :: MonadIO io => FilePath -> io () -- | Copy a file cp :: MonadIO io => FilePath -> FilePath -> io () -- | Remove a file rm :: MonadIO io => FilePath -> io () -- | Remove a directory rmdir :: MonadIO io => FilePath -> io () -- | Remove a directory tree (equivalent to rm -r) -- -- Use at your own risk rmtree :: MonadIO io => FilePath -> io () -- | Check if a file exists testfile :: MonadIO io => FilePath -> io Bool -- | Check if a directory exists testdir :: MonadIO io => FilePath -> io Bool -- | Get the current time date :: MonadIO io => io UTCTime -- | Get the time a file was last modified datefile :: MonadIO io => FilePath -> io UTCTime -- | Touch a file, updating the access and modification times to the -- current time -- -- Creates an empty file if it does not exist touch :: MonadIO io => FilePath -> io () -- | Time how long a command takes in monotonic wall clock time -- -- Returns the duration alongside the return value time :: MonadIO io => io a -> io (a, NominalDiffTime) -- | Get the system's host name hostname :: MonadIO io => io Text -- | Sleep for the given duration -- -- A numeric literal argument is interpreted as seconds. In other words, -- (sleep 2.0) will sleep for two seconds. sleep :: MonadIO io => NominalDiffTime -> io () -- | Exit with the given exit code -- -- An exit code of 0 indicates success exit :: MonadIO io => ExitCode -> io a -- | Throw an exception using the provided Text message die :: MonadIO io => Text -> io a -- | Analogous to && in Bash -- -- Runs the second command only if the first one returns -- ExitSuccess (.&&.) :: IO ExitCode -> IO ExitCode -> IO ExitCode -- | Analogous to || in Bash -- -- Run the second command only if the first one returns -- ExitFailure (.||.) :: IO ExitCode -> IO ExitCode -> IO ExitCode -- | Acquire a Managed read-only Handle from a -- FilePath readonly :: FilePath -> Managed Handle -- | Acquire a Managed write-only Handle from a -- FilePath writeonly :: FilePath -> Managed Handle -- | Acquire a Managed append-only Handle from a -- FilePath appendonly :: FilePath -> Managed Handle -- | Create a temporary file underneath the given directory -- -- Deletes the temporary file when done mktemp :: FilePath -> Text -> Managed (FilePath, Handle) -- | Create a temporary directory underneath the given directory -- -- Deletes the temporary directory when done mktempdir :: FilePath -> Text -> Managed FilePath -- | Fork a thread, acquiring an Async value fork :: IO a -> Managed (Async a) -- | Wait for an asynchronous action to complete, and return its value. If -- the asynchronous action threw an exception, then the exception is -- re-thrown by wait. -- --
--   wait = atomically . waitSTM
--   
wait :: Async a -> IO a -- | Run a command using execvp, streaming stdout as -- lines of Text -- -- The command inherits stderr for the current process inproc :: Text -> [Text] -> Shell Text -> Shell Text -- | Run a command line using the shell, streaming stdout as lines -- of Text -- -- This command is more powerful than inproc, but highly -- vulnerable to code injection if you template the command line with -- untrusted input -- -- The command inherits stderr for the current process inshell :: Text -> Shell Text -> Shell Text -- | Read lines of Text from standard input stdin :: Shell Text -- | Read lines of Text from a file input :: FilePath -> Shell Text -- | Read lines of Text from a Handle inhandle :: Handle -> Shell Text -- | Stream lines of Text to standard output stdout :: MonadIO io => Shell Text -> io () -- | Stream lines of Text to a file output :: MonadIO io => FilePath -> Shell Text -> io () -- | Stream lines of Text to a Handle outhandle :: MonadIO io => Handle -> Shell Text -> io () -- | Stream lines of Text to append to a file append :: MonadIO io => FilePath -> Shell Text -> io () -- | Stream lines of Text to standard error stderr :: MonadIO io => Shell Text -> io () -- | Read in a stream's contents strictly strict :: MonadIO io => Shell Text -> io Text -- | Stream all immediate children of the given directory, excluding -- "." and ".." ls :: FilePath -> Shell FilePath -- | Stream all recursive descendents of the given directory lstree :: FilePath -> Shell FilePath -- | Combine the output of multiple Shells, in order cat :: [Shell a] -> Shell a -- | Keep all lines that match the given Pattern grep :: Pattern a -> Shell Text -> Shell Text -- | Replace all occurrences of a Pattern with its Text -- result -- -- Warning: Do not use a Pattern that matches the empty string, -- since it will match an infinite number of times sed :: Pattern Text -> Shell Text -> Shell Text -- | Search a directory recursively for all files matching the given -- Pattern find :: Pattern a -> FilePath -> Shell FilePath -- | A Stream of "y"s yes :: Shell Text -- | Limit a Shell to a fixed number of values limit :: Int -> Shell a -> Shell a -- | Limit a Shell to values that satisfy the predicate -- -- This terminates the stream on the first value that does not satisfy -- the predicate limitWhile :: (a -> Bool) -> Shell a -> Shell a -- | Cache a Shell's output so that repeated runs of the script will -- reuse the result of previous runs. You must supply a FilePath -- where the cached result will be stored. -- -- The stored result is only reused if the Shell successfully ran -- to completion without any exceptions. Note: on some platforms Ctrl-C -- will flush standard input and signal end of file before killing the -- program, which may trick the program into "successfully" completing. cache :: (Read a, Show a) => FilePath -> Shell a -> Shell a -- | Count the number of characters in the stream (like wc -c) -- -- This uses the convention that the elements of the stream are -- implicitly ended by newlines that are one character wide countChars :: Integral n => Fold Text n -- | Count the number of words in the stream (like wc -w) countWords :: Integral n => Fold Text n -- | Count the number of lines in the stream (like wc -l) -- -- This uses the convention that each element of the stream represents -- one line countLines :: Integral n => Fold Text n data Permissions :: * -- | Update a file or directory's user permissions -- --
--   chmod rwo        "foo.txt"  -- chmod u=rw foo.txt
--   chmod executable "foo.txt"  -- chmod u+x foo.txt
--   chmod nonwritable "foo.txt" -- chmod u-x foo.txt
--   
chmod :: MonadIO io => (Permissions -> Permissions) -> FilePath -> io Permissions -- | Get a file or directory's user permissions getmod :: MonadIO io => FilePath -> io Permissions -- | Set a file or directory's user permissions setmod :: MonadIO io => Permissions -> FilePath -> io () -- |
--   +r
--   
readable :: Permissions -> Permissions -- |
--   -r
--   
nonreadable :: Permissions -> Permissions -- |
--   +w
--   
writable :: Permissions -> Permissions -- |
--   -w
--   
nonwritable :: Permissions -> Permissions -- |
--   +x
--   
executable :: Permissions -> Permissions -- |
--   -x
--   
nonexecutable :: Permissions -> Permissions -- |
--   +s
--   
searchable :: Permissions -> Permissions -- |
--   -s
--   
nonsearchable :: Permissions -> Permissions -- |
--   -r -w -x
--   
ooo :: Permissions -> Permissions -- |
--   +r -w -x
--   
roo :: Permissions -> Permissions -- |
--   -r +w -x
--   
owo :: Permissions -> Permissions -- |
--   -r -w +x
--   
oox :: Permissions -> Permissions -- |
--   -r -w +s
--   
oos :: Permissions -> Permissions -- |
--   +r +w -x
--   
rwo :: Permissions -> Permissions -- |
--   +r -w +x
--   
rox :: Permissions -> Permissions -- |
--   +r -w +s
--   
ros :: Permissions -> Permissions -- |
--   -r +w +x
--   
owx :: Permissions -> Permissions -- |
--   +r +w +x
--   
rwx :: Permissions -> Permissions rws :: Permissions -> Permissions -- | Get the size of a file or a directory du :: MonadIO io => FilePath -> io Size -- | An abstract file size -- -- Specify the units you want by using an accessor like kilobytes -- -- The Num instance for Size interprets numeric literals as -- bytes data Size -- | Extract a size in bytes bytes :: Integral n => Size -> n -- |
--   1 kilobyte = 1000 bytes
--   
kilobytes :: Integral n => Size -> n -- |
--   1 megabyte = 1000 kilobytes
--   
megabytes :: Integral n => Size -> n -- |
--   1 gigabyte = 1000 megabytes
--   
gigabytes :: Integral n => Size -> n -- |
--   1 terabyte = 1000 gigabytes
--   
terabytes :: Integral n => Size -> n -- |
--   1 kibibyte = 1024 bytes
--   
kibibytes :: Integral n => Size -> n -- |
--   1 mebibyte = 1024 kibibytes
--   
mebibytes :: Integral n => Size -> n -- |
--   1 gibibyte = 1024 mebibytes
--   
gibibytes :: Integral n => Size -> n -- |
--   1 tebibyte = 1024 gibibytes
--   
tebibytes :: Integral n => Size -> n instance Num Size instance Show Size -- | See Turtle.Tutorial to learn how to use this library or -- Turtle.Prelude for a quick-start guide. -- -- Here is the recommended way to import this library: -- --
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import Turtle
--   import Prelude hiding (FilePath)
--   
-- -- 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 Patterns, which are like more -- powerful regular expressions -- -- Turtle.Shell provides a Shell abstraction for building -- streaming, exception-safe pipelines -- -- Turtle.Prelude provides a library of Unix-like utilities to get -- you started with basic shell-like programming within Haskell -- -- Control.Applicative provides two classes: -- -- -- -- Control.Monad provides two classes: -- -- -- -- Control.Monad.IO.Class provides one class: -- -- -- -- Data.Monoid provides one class: -- -- -- -- Control.Monad.Managed.Safe provides Managed resources -- -- Filesystem.Path.CurrentOS provides FilePath-manipulation -- utilities -- -- Additionally, you might also want to import the following modules -- qualified: -- -- module Turtle -- | Efficient representation of a left fold that preserves the fold's step -- function, initial accumulator, and extraction function -- -- This allows the Applicative instance to assemble derived folds -- that traverse the container only once -- -- A 'Fold a b' processes elements of type a and results in -- a value of type b. data Fold a b :: * -> * -> * -- | Fold step initial extract Fold :: (x -> a -> x) -> x -> (x -> b) -> Fold a b -- | Like Fold, but monadic. -- -- A 'FoldM m a b' processes elements of type a and results -- in a monadic value of type m b. data FoldM (m :: * -> *) a b :: (* -> *) -> * -> * -> * -- | FoldM step initial extract FoldM :: (x -> a -> m x) -> m x -> (x -> m b) -> FoldM m a b -- | A space efficient, packed, unboxed Unicode text type. data Text :: * -- | This is the simplest representation of UTC. It consists of the day -- number, and a time offset from midnight. Note that if a day has a leap -- second added to it, it will have 86401 seconds. data UTCTime :: * -- | This is a length of time, as measured by UTC. Conversion functions -- will treat it as seconds. It has a precision of 10^-12 s. It ignores -- leap-seconds, so it's not necessarily a fixed amount of clock time. -- For instance, 23:00 UTC + 2 hours of NominalDiffTime = 01:00 UTC (+ 1 -- day), regardless of whether a leap-second intervened. data NominalDiffTime :: * -- | Haskell defines operations to read and write characters from and to -- files, represented by values of type Handle. Each value of -- this type is a handle: a record used by the Haskell run-time -- system to manage I/O with file system objects. A handle has at -- least the following properties: -- -- -- -- Most handles will also have a current I/O position indicating where -- the next input or output operation will occur. A handle is -- readable if it manages only input or both input and output; -- likewise, it is writable if it manages only output or both -- input and output. A handle is open when first allocated. Once -- it is closed it can no longer be used for either input or output, -- though an implementation cannot re-use its storage while references -- remain to it. Handles are in the Show and Eq classes. -- The string produced by showing a handle is system dependent; it should -- include enough information to identify the handle for debugging. A -- handle is equal according to == only to itself; no attempt is -- made to compare the internal state of different handles for equality. data Handle :: * -- | Defines the exit codes that a program can return. data ExitCode :: * -- | indicates successful termination; ExitSuccess :: ExitCode -- | indicates program failure with an exit code. The exact interpretation -- of the code is operating-system dependent. In particular, some values -- may be prohibited (e.g. 0 on a POSIX-compliant system). ExitFailure :: Int -> ExitCode -- | Class for string-like datastructures; used by the overloaded string -- extension (-XOverloadedStrings in GHC). class IsString a fromString :: IsString a => String -> a -- | & is a reverse application operator. This provides -- notational convenience. Its precedence is one higher than that of the -- forward application operator $, which allows & to be -- nested in $. (&) :: a -> (a -> b) -> b -- | Use turtle if you want to write light-weight and maintainable -- shell scripts. -- -- turtle embeds shell scripting directly within Haskell for -- three main reasons: -- -- -- --
--   $ stack install turtle
--   
module Turtle.Tutorial