-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Shell programming, Haskell-style
--   
--   <tt>turtle</tt> is a reimplementation of the Unix command line
--   environment in Haskell so that you can use Haskell as both a shell and
--   a scripting language.
--   
--   Features include:
--   
--   <ul>
--   <li>Batteries included: Command an extended suite of predefined
--   utilities</li>
--   <li>Interoperability: You can still run external shell commands</li>
--   <li>Portability: Works on Windows, OS X, and Linux</li>
--   <li>Exception safety: Safely acquire and release resources</li>
--   <li>Streaming: Transform or fold command output in constant space</li>
--   <li>Patterns: Use typed regular expressions that can parse structured
--   values</li>
--   <li>Formatting: Type-safe <tt>printf</tt>-style text formatting</li>
--   <li>Modern: Supports <tt>text</tt></li>
--   </ul>
--   
--   Read <a>Turtle.Tutorial</a> for a detailed tutorial or
--   <a>Turtle.Prelude</a> for a quick-start guide
--   
--   <tt>turtle</tt> is designed to be beginner-friendly, but as a result
--   lacks certain features, like tracing commands. If you feel comfortable
--   using <tt>turtle</tt> then you should also check out the
--   <tt>Shelly</tt> library which provides similar functionality.
@package turtle
@version 1.6.2

module Turtle.Line

-- | A line of text (does not contain newlines).
data Line

-- | Convert a line to a text value.
lineToText :: Line -> Text

-- | Split text into lines. The inverse of <a>linesToText</a>.
textToLines :: Text -> NonEmpty Line

-- | Merge lines into a single text value.
linesToText :: [Line] -> Text

-- | Try to convert a text value into a line. Precondition (checked): the
--   argument does not contain newlines.
textToLine :: Text -> Maybe Line

-- | Convert a text value into a line. Precondition (unchecked): the
--   argument does not contain newlines.
unsafeTextToLine :: Text -> Line

-- | The <a>NewlineForbidden</a> exception is thrown when you construct a
--   <a>Line</a> using an overloaded string literal or by calling
--   <a>fromString</a> explicitly and the supplied string contains
--   newlines. This is a programming error to do so: if you aren't sure
--   that the input string is newline-free, do not rely on the
--   <tt><a>IsString</a> <a>Line</a></tt> instance.
--   
--   When debugging, it might be useful to look for implicit invocations of
--   <a>fromString</a> for <a>Line</a>:
--   
--   <pre>
--   &gt;&gt;&gt; sh (do { line &lt;- "Hello\nWorld"; echo line })
--   *** Exception: NewlineForbidden
--   </pre>
--   
--   In the above example, <tt>echo</tt> expects its argument to be a
--   <a>Line</a>, thus <tt>line :: <a>Line</a></tt>. Since we bind
--   <tt>line</tt> in <tt>Shell</tt>, the string literal
--   <tt>"Hello\nWorld"</tt> has type <tt><tt>Shell</tt> <a>Line</a></tt>.
--   The <tt><a>IsString</a> (<tt>Shell</tt> <a>Line</a>)</tt> instance
--   delegates the construction of a <a>Line</a> to the <tt><a>IsString</a>
--   <a>Line</a></tt> instance, where the exception is thrown.
--   
--   To fix the problem, use <a>textToLines</a>:
--   
--   <pre>
--   &gt;&gt;&gt; sh (do { line &lt;- select (textToLines "Hello\nWorld"); echo line })
--   Hello
--   World
--   </pre>
data NewlineForbidden
NewlineForbidden :: NewlineForbidden
instance GHC.Show.Show Turtle.Line.NewlineForbidden
instance GHC.Base.Monoid Turtle.Line.Line
instance GHC.Show.Show Turtle.Line.Line
instance GHC.Classes.Ord Turtle.Line.Line
instance GHC.Classes.Eq Turtle.Line.Line
instance GHC.Base.Semigroup Turtle.Line.Line
instance Data.String.IsString Turtle.Line.Line
instance GHC.Exception.Type.Exception Turtle.Line.NewlineForbidden


-- | Minimalist implementation of type-safe formatted strings, borrowing
--   heavily from the implementation of the <tt>formatting</tt> package.
--   
--   Example use of this module:
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings
--   
--   &gt;&gt;&gt; import Turtle.Format
--   
--   &gt;&gt;&gt; format ("This is a "%s%" string that takes "%d%" arguments") "format" 2
--   "This is a format string that takes 2 arguments"
--   </pre>
--   
--   A <a>Format</a> string that takes no arguments has this type:
--   
--   <pre>
--   "I take 0 arguments" :: Format r r
--   
--   format "I take 0 arguments" :: Text
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; format "I take 0 arguments"
--   "I take 0 arguments"
--   </pre>
--   
--   A <a>Format</a> string that takes one argument has this type:
--   
--   <pre>
--   "I take "%d%" arguments" :: Format r (Int -&gt; r)
--   
--   format ("I take "%d%" argument") :: Int -&gt; Text
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; format ("I take "%d%" argument") 1
--   "I take 1 argument"
--   </pre>
--   
--   A <a>Format</a> string that takes two arguments has this type:
--   
--   <pre>
--   "I "%s%" "%d%" arguments" :: Format r (Text -&gt; Int -&gt; r)
--   
--   format ("I "%s%" "%d%" arguments") :: Text -&gt; Int -&gt; Text
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; format ("I "%s%" "%d%" arguments") "take" 2
--   "I take 2 arguments"
--   </pre>
module Turtle.Format

-- | A <a>Format</a> string
newtype Format a b
Format :: ((Text -> a) -> b) -> Format a b
[>>-] :: Format a b -> (Text -> a) -> b

-- | Concatenate two <a>Format</a> strings
(%) :: Format b c -> Format a b -> Format a c

-- | Convert a <a>Format</a> string to a print function that takes zero or
--   more typed arguments and returns a <a>Text</a> string
format :: Format Text r -> r

-- | Print a <a>Format</a> string to standard output (without a trailing
--   newline)
--   
--   <pre>
--   &gt;&gt;&gt; printf ("Hello, "%s%"!\n") "world"
--   Hello, world!
--   </pre>
printf :: MonadIO io => Format (io ()) r -> r

-- | Print a <a>Format</a> string to standard err (without a trailing
--   newline)
--   
--   <pre>
--   &gt;&gt;&gt; eprintf ("Hello, "%s%"!\n") "world"
--   Hello, world!
--   </pre>
eprintf :: MonadIO io => Format (io ()) r -> r

-- | Create your own format specifier
makeFormat :: (a -> Text) -> Format r (a -> r)

-- | <a>Format</a> any <a>Show</a>able value
--   
--   <pre>
--   &gt;&gt;&gt; format w True
--   "True"
--   </pre>
w :: Show a => Format r (a -> r)

-- | <a>Format</a> an <a>Integral</a> value as a signed decimal
--   
--   <pre>
--   &gt;&gt;&gt; format d 25
--   "25"
--   
--   &gt;&gt;&gt; format d (-25)
--   "-25"
--   </pre>
d :: Integral n => Format r (n -> r)

-- | <a>Format</a> a <a>Word</a> value as an unsigned decimal
--   
--   <pre>
--   &gt;&gt;&gt; format u 25
--   "25"
--   </pre>
u :: Format r (Word -> r)

-- | <a>Format</a> a <a>Word</a> value as an unsigned octal number
--   
--   <pre>
--   &gt;&gt;&gt; format o 25
--   "31"
--   </pre>
o :: Format r (Word -> r)

-- | <a>Format</a> a <a>Word</a> value as an unsigned hexadecimal number
--   (without a leading "0x")
--   
--   <pre>
--   &gt;&gt;&gt; format x 25
--   "19"
--   </pre>
x :: Format r (Word -> r)

-- | <a>Format</a> a <a>Double</a> using decimal notation with 6 digits of
--   precision
--   
--   <pre>
--   &gt;&gt;&gt; format f 25.1
--   "25.100000"
--   </pre>
f :: Format r (Double -> r)

-- | <a>Format</a> a <a>Double</a> using scientific notation with 6 digits
--   of precision
--   
--   <pre>
--   &gt;&gt;&gt; format e 25.1
--   "2.510000e1"
--   </pre>
e :: Format r (Double -> r)

-- | <a>Format</a> a <a>Double</a> using decimal notation for small
--   exponents and scientific notation for large exponents
--   
--   <pre>
--   &gt;&gt;&gt; format g 25.1
--   "25.100000"
--   
--   &gt;&gt;&gt; format g 123456789
--   "1.234568e8"
--   
--   &gt;&gt;&gt; format g 0.00000000001
--   "1.000000e-11"
--   </pre>
g :: Format r (Double -> r)

-- | <a>Format</a> that inserts <a>Text</a>
--   
--   <pre>
--   &gt;&gt;&gt; format s "ABC"
--   "ABC"
--   </pre>
s :: Format r (Text -> r)

-- | <a>Format</a> that inserts a <a>Line</a>
--   
--   <pre>
--   &gt;&gt;&gt; format l "ABC"
--   "ABC"
--   </pre>
l :: Format r (Line -> r)

-- | <a>Format</a> a <a>FilePath</a> into <a>Text</a>
fp :: Format r (FilePath -> r)

-- | <a>Format</a> a <a>UTCTime</a> into <a>Text</a>
utc :: Format r (UTCTime -> r)

-- | Convert a <a>Show</a>able value to any type that implements
--   <a>IsString</a> (such as <a>Text</a>)
--   
--   <pre>
--   &gt;&gt;&gt; repr (1,2)
--   "(1,2)"
--   </pre>
repr :: (Show a, IsString text) => a -> text
instance Control.Category.Category Turtle.Format.Format
instance (a GHC.Types.~ b) => Data.String.IsString (Turtle.Format.Format a b)


-- | Example usage of this module:
--   
--   <pre>
--   -- options.hs
--   
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import Turtle
--   
--   parser :: Parser (Text, Int)
--   parser = (,) &lt;$&gt; optText "name" 'n' "Your first name"
--                &lt;*&gt; optInt  "age"  'a' "Your current age"
--   
--   main = do
--       (name, age) &lt;- options "Greeting script" parser
--       echo (repr (format ("Hello there, "%s) name))
--       echo (repr (format ("You are "%d%" years old") age))
--   </pre>
--   
--   <pre>
--   $ ./options --name John --age 42
--   Hello there, John
--   You are 42 years old
--   </pre>
--   
--   <pre>
--   $ ./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
--   </pre>
--   
--   See the <a>Turtle.Tutorial</a> module which contains more examples on
--   how to use command-line parsing.
module Turtle.Options
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 <a>ArgName</a> of <tt>"name"</tt> will
--   create a <tt>--name</tt> flag with a <tt>NAME</tt> metavariable
newtype ArgName
ArgName :: Text -> ArgName
[getArgName] :: ArgName -> Text

-- | The name of a sub-command
--   
--   This is lower-cased to create a sub-command. For example, a
--   <a>CommandName</a> of <tt>"Name"</tt> will parse <tt>name</tt> on the
--   command line before parsing the remaining arguments using the
--   command's subparser.
newtype CommandName
CommandName :: Text -> CommandName
[getCommandName] :: CommandName -> Text

-- | The short one-character abbreviation for a flag (i.e. <tt>-n</tt>)
type ShortName = Char

-- | A brief description of what your program does
--   
--   This description will appear in the header of the <tt>--help</tt>
--   output
newtype Description
Description :: Doc -> Description
[getDescription] :: Description -> Doc

-- | A helpful message explaining what a flag does
--   
--   This will appear in the <tt>--help</tt> output
newtype HelpMessage
HelpMessage :: Text -> HelpMessage
[getHelpMessage] :: HelpMessage -> Text

-- | This parser returns <a>True</a> if the given flag is set and
--   <a>False</a> if the flag is absent
switch :: ArgName -> ShortName -> Optional HelpMessage -> Parser Bool

-- | Parse a <a>Text</a> value as a flag-based option
optText :: ArgName -> ShortName -> Optional HelpMessage -> Parser Text

-- | Parse a <a>Line</a> value as a flag-based option
optLine :: ArgName -> ShortName -> Optional HelpMessage -> Parser Line

-- | Parse an <a>Int</a> as a flag-based option
optInt :: ArgName -> ShortName -> Optional HelpMessage -> Parser Int

-- | Parse an <a>Integer</a> as a flag-based option
optInteger :: ArgName -> ShortName -> Optional HelpMessage -> Parser Integer

-- | Parse a <a>Double</a> as a flag-based option
optDouble :: ArgName -> ShortName -> Optional HelpMessage -> Parser Double

-- | Parse a <a>FilePath</a> value as a flag-based option
optPath :: ArgName -> ShortName -> Optional HelpMessage -> Parser FilePath

-- | Parse any type that implements <a>Read</a>
optRead :: Read a => ArgName -> ShortName -> Optional HelpMessage -> Parser a

-- | Build a flag-based option parser for any type by providing a
--   <a>Text</a>-parsing function
opt :: (Text -> Maybe a) -> ArgName -> ShortName -> Optional HelpMessage -> Parser a

-- | Parse a <a>Text</a> as a positional argument
argText :: ArgName -> Optional HelpMessage -> Parser Text

-- | Parse a <a>Line</a> as a positional argument
argLine :: ArgName -> Optional HelpMessage -> Parser Line

-- | Parse an <a>Int</a> as a positional argument
argInt :: ArgName -> Optional HelpMessage -> Parser Int

-- | Parse an <a>Integer</a> as a positional argument
argInteger :: ArgName -> Optional HelpMessage -> Parser Integer

-- | Parse a <a>Double</a> as a positional argument
argDouble :: ArgName -> Optional HelpMessage -> Parser Double

-- | Parse a <a>FilePath</a> as a positional argument
argPath :: ArgName -> Optional HelpMessage -> Parser FilePath

-- | Parse any type that implements <a>Read</a> as a positional argument
argRead :: Read a => ArgName -> Optional HelpMessage -> Parser a

-- | Build a positional argument parser for any type by providing a
--   <a>Text</a>-parsing function
arg :: (Text -> Maybe a) -> ArgName -> Optional HelpMessage -> Parser a

-- | Create a sub-command that parses <a>CommandName</a> and then parses
--   the rest of the command-line arguments
--   
--   The sub-command will have its own <a>Description</a> and help text
subcommand :: CommandName -> Description -> Parser a -> Parser a

-- | Create a named group of sub-commands
subcommandGroup :: forall a. Description -> [(CommandName, Description, Parser a)] -> Parser a

-- | Parse the given options from the command line
options :: MonadIO io => Description -> Parser a -> io a

-- | Parse the given options from the command line and add additional
--   information
--   
--   Extended version of <tt>options</tt> with program version header and
--   footer information
optionsExt :: MonadIO io => Header -> Footer -> Description -> Version -> Parser a -> io a
instance Data.String.IsString Turtle.Options.ArgName
instance Data.String.IsString Turtle.Options.CommandName
instance Data.String.IsString Turtle.Options.Description
instance Data.String.IsString Turtle.Options.Header
instance Data.String.IsString Turtle.Options.Footer
instance Data.String.IsString Turtle.Options.HelpMessage


-- | Use this module to either:
--   
--   <ul>
--   <li>match <a>Text</a> with light-weight backtracking patterns,
--   or:</li>
--   <li>parse structured values from <a>Text</a>.</li>
--   </ul>
--   
--   Example usage:
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings
--   
--   &gt;&gt;&gt; match ("can" &lt;|&gt; "cat") "cat"
--   ["cat"]
--   
--   &gt;&gt;&gt; match ("can" &lt;|&gt; "cat") "dog"
--   []
--   
--   &gt;&gt;&gt; match (decimal `sepBy` ",") "1,2,3"
--   [[1,2,3]]
--   </pre>
--   
--   This pattern has unlimited backtracking, and will return as many
--   solutions as possible:
--   
--   <pre>
--   &gt;&gt;&gt; match (prefix (star anyChar)) "123"
--   ["123","12","1",""]
--   </pre>
--   
--   Use <tt>do</tt> notation to structure more complex patterns:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   let bit = ("0" *&gt; pure False) &lt;|&gt; ("1" *&gt; pure True) :: Pattern Bool;
--       portableBitMap = do
--           { "P1"
--           ; width  &lt;- spaces1 *&gt; decimal
--           ; height &lt;- spaces1 *&gt; decimal
--           ; count width (count height (spaces1 *&gt; bit))
--           };
--   in  match (prefix portableBitMap) "P1\n2 2\n0 0\n1 0\n"
--   :}
--   [[[False,False],[True,False]]]
--   </pre>
module Turtle.Pattern

-- | A fully backtracking pattern that parses an <tt>'a'</tt> from some
--   <a>Text</a>
data Pattern a

-- | Match a <a>Pattern</a> against a <a>Text</a> input, returning all
--   possible solutions
--   
--   The <a>Pattern</a> must match the entire <a>Text</a>
match :: Pattern a -> Text -> [a]

-- | Match any character
--   
--   <pre>
--   &gt;&gt;&gt; match anyChar "1"
--   "1"
--   
--   &gt;&gt;&gt; match anyChar ""
--   ""
--   </pre>
anyChar :: Pattern Char

-- | Matches the end of input
--   
--   <pre>
--   &gt;&gt;&gt; match eof "1"
--   []
--   
--   &gt;&gt;&gt; match eof ""
--   [()]
--   </pre>
eof :: Pattern ()

-- | Synonym for <a>anyChar</a>
dot :: Pattern Char

-- | Match any character that satisfies the given predicate
--   
--   <pre>
--   &gt;&gt;&gt; match (satisfy (== '1')) "1"
--   "1"
--   
--   &gt;&gt;&gt; match (satisfy (== '2')) "1"
--   ""
--   </pre>
satisfy :: (Char -> Bool) -> Pattern Char

-- | Match a specific character
--   
--   <pre>
--   &gt;&gt;&gt; match (char '1') "1"
--   "1"
--   
--   &gt;&gt;&gt; match (char '2') "1"
--   ""
--   </pre>
char :: Char -> Pattern Char

-- | Match any character except the given one
--   
--   <pre>
--   &gt;&gt;&gt; match (notChar '2') "1"
--   "1"
--   
--   &gt;&gt;&gt; match (notChar '1') "1"
--   ""
--   </pre>
notChar :: Char -> Pattern Char

-- | Match a specific string
--   
--   <pre>
--   &gt;&gt;&gt; match (text "123") "123"
--   ["123"]
--   </pre>
--   
--   You can also omit the <a>text</a> function if you enable the
--   <tt>OverloadedStrings</tt> extension:
--   
--   <pre>
--   &gt;&gt;&gt; match "123" "123"
--   ["123"]
--   </pre>
text :: Text -> Pattern Text

-- | Match a specific string in a case-insensitive way
--   
--   This only handles ASCII strings
--   
--   <pre>
--   &gt;&gt;&gt; match (asciiCI "abc") "ABC"
--   ["ABC"]
--   </pre>
asciiCI :: Text -> Pattern Text

-- | Match any one of the given characters
--   
--   <pre>
--   &gt;&gt;&gt; match (oneOf "1a") "1"
--   "1"
--   
--   &gt;&gt;&gt; match (oneOf "2a") "1"
--   ""
--   </pre>
oneOf :: [Char] -> Pattern Char

-- | Match anything other than the given characters
--   
--   <pre>
--   &gt;&gt;&gt; match (noneOf "2a") "1"
--   "1"
--   
--   &gt;&gt;&gt; match (noneOf "1a") "1"
--   ""
--   </pre>
noneOf :: [Char] -> Pattern Char

-- | Match a whitespace character
--   
--   <pre>
--   &gt;&gt;&gt; match space " "
--   " "
--   
--   &gt;&gt;&gt; match space "1"
--   ""
--   </pre>
space :: Pattern Char

-- | Match zero or more whitespace characters
--   
--   <pre>
--   &gt;&gt;&gt; match spaces "  "
--   ["  "]
--   
--   &gt;&gt;&gt; match spaces ""
--   [""]
--   </pre>
spaces :: Pattern Text

-- | Match one or more whitespace characters
--   
--   <pre>
--   &gt;&gt;&gt; match spaces1 "  "
--   ["  "]
--   
--   &gt;&gt;&gt; match spaces1 ""
--   []
--   </pre>
spaces1 :: Pattern Text

-- | Match the tab character (<tt>'t'</tt>)
--   
--   <pre>
--   &gt;&gt;&gt; match tab "\t"
--   "\t"
--   
--   &gt;&gt;&gt; match tab " "
--   ""
--   </pre>
tab :: Pattern Char

-- | Match the newline character (<tt>'n'</tt>)
--   
--   <pre>
--   &gt;&gt;&gt; match newline "\n"
--   "\n"
--   
--   &gt;&gt;&gt; match newline " "
--   ""
--   </pre>
newline :: Pattern Char

-- | Matches a carriage return (<tt>'r'</tt>) followed by a newline
--   (<tt>'n'</tt>)
--   
--   <pre>
--   &gt;&gt;&gt; match crlf "\r\n"
--   ["\r\n"]
--   
--   &gt;&gt;&gt; match crlf "\n\r"
--   []
--   </pre>
crlf :: Pattern Text

-- | Match an uppercase letter
--   
--   <pre>
--   &gt;&gt;&gt; match upper "A"
--   "A"
--   
--   &gt;&gt;&gt; match upper "a"
--   ""
--   </pre>
upper :: Pattern Char

-- | Match a lowercase letter
--   
--   <pre>
--   &gt;&gt;&gt; match lower "a"
--   "a"
--   
--   &gt;&gt;&gt; match lower "A"
--   ""
--   </pre>
lower :: Pattern Char

-- | Match a letter or digit
--   
--   <pre>
--   &gt;&gt;&gt; match alphaNum "1"
--   "1"
--   
--   &gt;&gt;&gt; match alphaNum "a"
--   "a"
--   
--   &gt;&gt;&gt; match alphaNum "A"
--   "A"
--   
--   &gt;&gt;&gt; match alphaNum "."
--   ""
--   </pre>
alphaNum :: Pattern Char

-- | Match a letter
--   
--   <pre>
--   &gt;&gt;&gt; match letter "A"
--   "A"
--   
--   &gt;&gt;&gt; match letter "a"
--   "a"
--   
--   &gt;&gt;&gt; match letter "1"
--   ""
--   </pre>
letter :: Pattern Char

-- | Match a digit
--   
--   <pre>
--   &gt;&gt;&gt; match digit "1"
--   "1"
--   
--   &gt;&gt;&gt; match digit "a"
--   ""
--   </pre>
digit :: Pattern Char

-- | Match a hexadecimal digit
--   
--   <pre>
--   &gt;&gt;&gt; match hexDigit "1"
--   "1"
--   
--   &gt;&gt;&gt; match hexDigit "A"
--   "A"
--   
--   &gt;&gt;&gt; match hexDigit "a"
--   "a"
--   
--   &gt;&gt;&gt; match hexDigit "g"
--   ""
--   </pre>
hexDigit :: Pattern Char

-- | Match an octal digit
--   
--   <pre>
--   &gt;&gt;&gt; match octDigit "1"
--   "1"
--   
--   &gt;&gt;&gt; match octDigit "9"
--   ""
--   </pre>
octDigit :: Pattern Char

-- | Match an unsigned decimal number
--   
--   <pre>
--   &gt;&gt;&gt; match decimal  "123"
--   [123]
--   
--   &gt;&gt;&gt; match decimal "-123"
--   []
--   </pre>
decimal :: Num n => Pattern n

-- | Transform a numeric parser to accept an optional leading <tt>'+'</tt>
--   or <tt>'-'</tt> sign
--   
--   <pre>
--   &gt;&gt;&gt; match (signed decimal) "+123"
--   [123]
--   
--   &gt;&gt;&gt; match (signed decimal) "-123"
--   [-123]
--   
--   &gt;&gt;&gt; match (signed decimal)  "123"
--   [123]
--   </pre>
signed :: Num a => Pattern a -> Pattern a

-- | Use this to match the prefix of a string
--   
--   <pre>
--   &gt;&gt;&gt; match         "A"  "ABC"
--   []
--   
--   &gt;&gt;&gt; match (prefix "A") "ABC"
--   ["A"]
--   </pre>
prefix :: Pattern a -> Pattern a

-- | Use this to match the suffix of a string
--   
--   <pre>
--   &gt;&gt;&gt; match         "C"  "ABC"
--   []
--   
--   &gt;&gt;&gt; match (suffix "C") "ABC"
--   ["C"]
--   </pre>
suffix :: Pattern a -> Pattern a

-- | Use this to match the interior of a string
--   
--   <pre>
--   &gt;&gt;&gt; match      "B"  "ABC"
--   []
--   
--   &gt;&gt;&gt; match (has "B") "ABC"
--   ["B"]
--   </pre>
has :: Pattern a -> Pattern a

-- | Match the entire string if it begins with the given pattern
--   
--   This returns the entire string, not just the matched prefix
--   
--   <pre>
--   &gt;&gt;&gt; match (begins  "A"             ) "ABC"
--   ["ABC"]
--   
--   &gt;&gt;&gt; match (begins ("A" *&gt; pure "1")) "ABC"
--   ["1BC"]
--   </pre>
begins :: Pattern Text -> Pattern Text

-- | Match the entire string if it ends with the given pattern
--   
--   This returns the entire string, not just the matched prefix
--   
--   <pre>
--   &gt;&gt;&gt; match (ends  "C"             ) "ABC"
--   ["ABC"]
--   
--   &gt;&gt;&gt; match (ends ("C" *&gt; pure "1")) "ABC"
--   ["AB1"]
--   </pre>
ends :: Pattern Text -> Pattern Text

-- | Match the entire string if it contains the given pattern
--   
--   This returns the entire string, not just the interior pattern
--   
--   <pre>
--   &gt;&gt;&gt; match (contains  "B"             ) "ABC"
--   ["ABC"]
--   
--   &gt;&gt;&gt; match (contains ("B" *&gt; pure "1")) "ABC"
--   ["A1C"]
--   </pre>
contains :: Pattern Text -> Pattern Text

-- | <tt>(<a>invert</a> p)</tt> succeeds if <tt>p</tt> fails and fails if
--   <tt>p</tt> succeeds
--   
--   <pre>
--   &gt;&gt;&gt; match (invert "A") "A"
--   []
--   
--   &gt;&gt;&gt; match (invert "A") "B"
--   [()]
--   
--   &gt;&gt;&gt; match (invert "A") "AA"
--   [()]
--   </pre>
invert :: Pattern a -> Pattern ()

-- | Match a <a>Char</a>, but return <a>Text</a>
--   
--   <pre>
--   &gt;&gt;&gt; match (once (char '1')) "1"
--   ["1"]
--   
--   &gt;&gt;&gt; match (once (char '1')) ""
--   []
--   </pre>
once :: Pattern Char -> Pattern Text

-- | Parse 0 or more occurrences of the given character
--   
--   <pre>
--   &gt;&gt;&gt; match (star anyChar) "123"
--   ["123"]
--   
--   &gt;&gt;&gt; match (star anyChar) ""
--   [""]
--   </pre>
--   
--   See also: <a>chars</a>
star :: Pattern Char -> Pattern Text

-- | Parse 1 or more occurrences of the given character
--   
--   <pre>
--   &gt;&gt;&gt; match (plus digit) "123"
--   ["123"]
--   
--   &gt;&gt;&gt; match (plus digit) ""
--   []
--   </pre>
--   
--   See also: <a>chars1</a>
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 <a>selfless</a>
--   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
--   
--   <pre>
--   &gt;&gt;&gt; match (prefix (selfless (some anyChar))) "123"
--   ["1","12","123"]
--   
--   &gt;&gt;&gt; match (prefix           (some anyChar) ) "123"
--   ["123","12","1"]
--   </pre>
selfless :: Pattern a -> Pattern a

-- | Apply the patterns in the list in order, until one of them succeeds
--   
--   <pre>
--   &gt;&gt;&gt; match (choice ["cat", "dog", "egg"]) "egg"
--   ["egg"]
--   
--   &gt;&gt;&gt; match (choice ["cat", "dog", "egg"]) "cat"
--   ["cat"]
--   
--   &gt;&gt;&gt; match (choice ["cat", "dog", "egg"]) "fan"
--   []
--   </pre>
choice :: [Pattern a] -> Pattern a

-- | Apply the given pattern a fixed number of times, collecting the
--   results
--   
--   <pre>
--   &gt;&gt;&gt; match (count 3 anyChar) "123"
--   ["123"]
--   
--   &gt;&gt;&gt; match (count 4 anyChar) "123"
--   []
--   </pre>
count :: Int -> Pattern a -> Pattern [a]

-- | Apply the given pattern at least the given number of times, collecting
--   the results
--   
--   <pre>
--   &gt;&gt;&gt; match (lowerBounded 5 dot) "123"
--   []
--   
--   &gt;&gt;&gt; match (lowerBounded 2 dot) "123"
--   ["123"]
--   </pre>
lowerBounded :: Int -> Pattern a -> Pattern [a]

-- | Apply the given pattern 0 or more times, up to a given bound,
--   collecting the results
--   
--   <pre>
--   &gt;&gt;&gt; match (upperBounded 5 dot) "123"
--   ["123"]
--   
--   &gt;&gt;&gt; match (upperBounded 2 dot) "123"
--   []
--   
--   &gt;&gt;&gt; match ((,) &lt;$&gt; upperBounded 2 dot &lt;*&gt; chars) "123"
--   [("12","3"),("1","23")]
--   </pre>
upperBounded :: Int -> Pattern a -> Pattern [a]

-- | Apply the given pattern a number of times restricted by given lower
--   and upper bounds, collecting the results
--   
--   <pre>
--   &gt;&gt;&gt; match (bounded 2 5 "cat") "catcatcat"
--   [["cat","cat","cat"]]
--   
--   &gt;&gt;&gt; match (bounded 2 5 "cat") "cat"
--   []
--   
--   &gt;&gt;&gt; match (bounded 2 5 "cat") "catcatcatcatcatcat"
--   []
--   </pre>
--   
--   <a>bounded</a> could be implemented naively as follows:
--   
--   <pre>
--   bounded m n p = do
--     x &lt;- choice (map pure [m..n])
--     count x p
--   </pre>
bounded :: Int -> Int -> Pattern a -> Pattern [a]

-- | Transform a parser to a succeed with an empty value instead of failing
--   
--   See also: <a>optional</a>
--   
--   <pre>
--   &gt;&gt;&gt; match (option "1" &lt;&gt; "2") "12"
--   ["12"]
--   
--   &gt;&gt;&gt; match (option "1" &lt;&gt; "2") "2"
--   ["2"]
--   </pre>
option :: Monoid a => Pattern a -> Pattern a

-- | <tt>(between open close p)</tt> matches <tt>'p'</tt> in between
--   <tt>'open'</tt> and <tt>'close'</tt>
--   
--   <pre>
--   &gt;&gt;&gt; match (between (char '(') (char ')') (star anyChar)) "(123)"
--   ["123"]
--   
--   &gt;&gt;&gt; match (between (char '(') (char ')') (star anyChar)) "(123"
--   []
--   </pre>
between :: Pattern a -> Pattern b -> Pattern c -> Pattern c

-- | Discard the pattern's result
--   
--   <pre>
--   &gt;&gt;&gt; match (skip anyChar) "1"
--   [()]
--   
--   &gt;&gt;&gt; match (skip anyChar) ""
--   []
--   </pre>
skip :: Pattern a -> Pattern ()

-- | Restrict the pattern to consume no more than the given number of
--   characters
--   
--   <pre>
--   &gt;&gt;&gt; match (within 2 decimal) "12"
--   [12]
--   
--   &gt;&gt;&gt; match (within 2 decimal) "1"
--   [1]
--   
--   &gt;&gt;&gt; match (within 2 decimal) "123"
--   []
--   </pre>
within :: Int -> Pattern a -> Pattern a

-- | Require the pattern to consume exactly the given number of characters
--   
--   <pre>
--   &gt;&gt;&gt; match (fixed 2 decimal) "12"
--   [12]
--   
--   &gt;&gt;&gt; match (fixed 2 decimal) "1"
--   []
--   </pre>
fixed :: Int -> Pattern a -> Pattern a

-- | <tt>p <a>sepBy</a> sep</tt> matches zero or more occurrences of
--   <tt>p</tt> separated by <tt>sep</tt>
--   
--   <pre>
--   &gt;&gt;&gt; match (decimal `sepBy` char ',') "1,2,3"
--   [[1,2,3]]
--   
--   &gt;&gt;&gt; match (decimal `sepBy` char ',') ""
--   [[]]
--   </pre>
sepBy :: Pattern a -> Pattern b -> Pattern [a]

-- | <tt>p <a>sepBy1</a> sep</tt> matches one or more occurrences of
--   <tt>p</tt> separated by <tt>sep</tt>
--   
--   <pre>
--   &gt;&gt;&gt; match (decimal `sepBy1` ",") "1,2,3"
--   [[1,2,3]]
--   
--   &gt;&gt;&gt; match (decimal `sepBy1` ",") ""
--   []
--   </pre>
sepBy1 :: Pattern a -> Pattern b -> Pattern [a]

-- | Like <tt>star dot</tt> or <tt>star anyChar</tt>, except more efficient
chars :: Pattern Text

-- | Like <tt>plus dot</tt> or <tt>plus anyChar</tt>, except more efficient
chars1 :: Pattern Text
instance GHC.Base.MonadPlus Turtle.Pattern.Pattern
instance GHC.Base.Alternative Turtle.Pattern.Pattern
instance GHC.Base.Monad Turtle.Pattern.Pattern
instance GHC.Base.Applicative Turtle.Pattern.Pattern
instance GHC.Base.Functor Turtle.Pattern.Pattern
instance GHC.Base.Monoid a => GHC.Base.Semigroup (Turtle.Pattern.Pattern a)
instance GHC.Base.Monoid a => GHC.Base.Monoid (Turtle.Pattern.Pattern a)
instance GHC.Base.Monoid a => GHC.Num.Num (Turtle.Pattern.Pattern a)
instance (a GHC.Types.~ Data.Text.Internal.Text) => Data.String.IsString (Turtle.Pattern.Pattern a)


-- | You can think of <a>Shell</a> as <tt>[]</tt> + <a>IO</a> +
--   <tt>Managed</tt>. In fact, you can embed all three of them within a
--   <a>Shell</a>:
--   
--   <pre>
--   select ::        [a] -&gt; Shell a
--   liftIO ::      IO a  -&gt; Shell a
--   using  :: Managed a  -&gt; Shell a
--   </pre>
--   
--   Those three embeddings obey these laws:
--   
--   <pre>
--   do { x &lt;- select m; select (f x) } = select (do { x &lt;- m; f x })
--   do { x &lt;- liftIO m; liftIO (f x) } = liftIO (do { x &lt;- m; f x })
--   do { x &lt;- with   m; using  (f x) } = using  (do { x &lt;- m; f x })
--   
--   select (return x) = return x
--   liftIO (return x) = return x
--   using  (return x) = return x
--   </pre>
--   
--   ... and <a>select</a> obeys these additional laws:
--   
--   <pre>
--   select xs &lt;|&gt; select ys = select (xs &lt;|&gt; ys)
--   select empty = empty
--   </pre>
--   
--   You typically won't build <a>Shell</a>s using the <a>Shell</a>
--   constructor. Instead, use these functions to generate primitive
--   <a>Shell</a>s:
--   
--   <ul>
--   <li><a>empty</a>, to create a <a>Shell</a> that outputs nothing</li>
--   <li><a>return</a>, to create a <a>Shell</a> that outputs a single
--   value</li>
--   <li><a>select</a>, to range over a list of values within a
--   <a>Shell</a></li>
--   <li><a>liftIO</a>, to embed an <a>IO</a> action within a
--   <a>Shell</a></li>
--   <li><a>using</a>, to acquire a <tt>Managed</tt> resource within a
--   <a>Shell</a></li>
--   </ul>
--   
--   Then use these classes to combine those primitive <a>Shell</a>s into
--   larger <a>Shell</a>s:
--   
--   <ul>
--   <li><a>Alternative</a>, to concatenate <a>Shell</a> outputs using
--   (<a>&lt;|&gt;</a>)</li>
--   <li><a>Monad</a>, to build <a>Shell</a> comprehensions using
--   <tt>do</tt> notation</li>
--   </ul>
--   
--   If you still insist on building your own <a>Shell</a> from scratch,
--   then the <a>Shell</a> you build must satisfy this law:
--   
--   <pre>
--   -- For every shell `s`:
--   _foldShell s (FoldShell step begin done) = do
--       x' &lt;- _foldShell s (FoldShell step begin return)
--       done x'
--   </pre>
--   
--   ... which is a fancy way of saying that your <a>Shell</a> must call
--   <tt>'begin'</tt> exactly once when it begins and call <tt>'done'</tt>
--   exactly once when it ends.
module Turtle.Shell

-- | A <tt>(Shell a)</tt> is a protected stream of <tt>a</tt>'s with side
--   effects
newtype Shell a
Shell :: (forall r. FoldShell a r -> IO r) -> Shell a
[_foldShell] :: Shell a -> forall r. FoldShell a r -> IO r

-- | This is similar to <tt><a>FoldM</a> <a>IO</a></tt> except that the
--   <tt>begin</tt> field is pure
--   
--   This small difference is necessary to implement a well-behaved
--   <a>MonadCatch</a> instance for <a>Shell</a>
data FoldShell a b
FoldShell :: (x -> a -> IO x) -> x -> (x -> IO b) -> FoldShell a b

-- | Provided for backwards compatibility with versions of
--   <tt>turtle-1.4.*</tt> and older
_foldIO :: Shell a -> FoldM IO a r -> IO r

-- | Provided for ease of migration from versions of <tt>turtle-1.4.*</tt>
--   and older
_Shell :: (forall r. FoldM IO a r -> IO r) -> Shell a

-- | Use a <tt><a>FoldM</a> <a>IO</a></tt> to reduce the stream of
--   <tt>a</tt>'s produced by a <a>Shell</a>
foldIO :: MonadIO io => Shell a -> FoldM IO a r -> io r

-- | Use a <a>FoldShell</a> to reduce the stream of <tt>a</tt>'s produced
--   by a <a>Shell</a>
foldShell :: MonadIO io => Shell a -> FoldShell a b -> io b

-- | Use a <a>Fold</a> to reduce the stream of <tt>a</tt>'s produced by a
--   <a>Shell</a>
fold :: MonadIO io => Shell a -> Fold a b -> io b

-- | Flipped version of <a>fold</a>. Useful for reducing a stream of data
--   
--   <h4><b>Example</b></h4>
--   
--   Sum a <a>Shell</a> of numbers:
--   
--   <pre>
--   &gt;&gt;&gt; select [1, 2, 3] &amp; reduce Fold.sum
--   6
--   </pre>
reduce :: MonadIO io => Fold a b -> Shell a -> io b

-- | Run a <a>Shell</a> to completion, discarding any unused values
sh :: MonadIO io => Shell a -> io ()

-- | Run a <a>Shell</a> to completion, <a>print</a>ing any unused values
view :: (MonadIO io, Show a) => Shell a -> io ()

-- | Convert a list to a <a>Shell</a> that emits each element of the list
select :: Foldable f => f a -> Shell a
liftIO :: MonadIO m => IO a -> m a
using :: MonadManaged m => Managed a -> m a

-- | Convert an <a>IO</a> action that returns a <a>Maybe</a> into a
--   <a>Shell</a>
fromIO :: IO (Maybe a) -> Shell a
instance GHC.Base.Functor Turtle.Shell.Shell
instance GHC.Base.Applicative Turtle.Shell.Shell
instance GHC.Base.Monad Turtle.Shell.Shell
instance GHC.Base.Alternative Turtle.Shell.Shell
instance GHC.Base.MonadPlus Turtle.Shell.Shell
instance Control.Monad.IO.Class.MonadIO Turtle.Shell.Shell
instance Control.Monad.Managed.MonadManaged Turtle.Shell.Shell
instance Control.Monad.Catch.MonadThrow Turtle.Shell.Shell
instance Control.Monad.Catch.MonadCatch Turtle.Shell.Shell
instance Control.Monad.Fail.MonadFail Turtle.Shell.Shell
instance GHC.Base.Monoid a => GHC.Base.Semigroup (Turtle.Shell.Shell a)
instance GHC.Base.Monoid a => GHC.Base.Monoid (Turtle.Shell.Shell a)
instance GHC.Base.Monoid a => GHC.Num.Num (Turtle.Shell.Shell a)
instance Data.String.IsString a => Data.String.IsString (Turtle.Shell.Shell a)


-- | 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:
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings
--   
--   &gt;&gt;&gt; cd "/tmp"
--   
--   &gt;&gt;&gt; pwd
--   FilePath "/tmp"
--   </pre>
--   
--   Some commands are <a>Shell</a>s that emit streams of values.
--   <a>view</a> prints all values in a <a>Shell</a> stream:
--   
--   <pre>
--   &gt;&gt;&gt; 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"
--   
--   &gt;&gt;&gt; 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"
--   </pre>
--   
--   Use <a>fold</a> to reduce the output of a <a>Shell</a> stream:
--   
--   <pre>
--   &gt;&gt;&gt; import qualified Control.Foldl as Fold
--   
--   &gt;&gt;&gt; fold (ls "/usr") Fold.length
--   8
--   
--   &gt;&gt;&gt; fold (find (suffix "Browser.py") "/usr/lib") Fold.head
--   Just (FilePath "/usr/lib/python3.4/idlelib/ClassBrowser.py")
--   </pre>
--   
--   Create files using <a>output</a>:
--   
--   <pre>
--   &gt;&gt;&gt; output "foo.txt" ("123" &lt;|&gt; "456" &lt;|&gt; "ABC")
--   
--   &gt;&gt;&gt; realpath "foo.txt"
--   FilePath "/tmp/foo.txt"
--   </pre>
--   
--   Read in files using <a>input</a>:
--   
--   <pre>
--   &gt;&gt;&gt; stdout (input "foo.txt")
--   123
--   456
--   ABC
--   </pre>
--   
--   Format strings in a type safe way using <a>format</a>:
--   
--   <pre>
--   &gt;&gt;&gt; dir &lt;- pwd
--   
--   &gt;&gt;&gt; format ("I am in the "%fp%" directory") dir
--   "I am in the /tmp directory"
--   </pre>
--   
--   Commands like <a>grep</a>, <a>sed</a> and <a>find</a> accept arbitrary
--   <a>Pattern</a>s
--   
--   <pre>
--   &gt;&gt;&gt; stdout (grep ("123" &lt;|&gt; "ABC") (input "foo.txt"))
--   123
--   ABC
--   
--   &gt;&gt;&gt; let exclaim = fmap (&lt;&gt; "!") (plus digit)
--   
--   &gt;&gt;&gt; stdout (sed exclaim (input "foo.txt"))
--   123!
--   456!
--   ABC
--   </pre>
--   
--   Note that <a>grep</a> and <a>find</a> differ from their Unix
--   counterparts by requiring that the <a>Pattern</a> matches the entire
--   line or file name by default. However, you can optionally match the
--   prefix, suffix, or interior of a line:
--   
--   <pre>
--   &gt;&gt;&gt; stdout (grep (has    "2") (input "foo.txt"))
--   123
--   
--   &gt;&gt;&gt; stdout (grep (prefix "1") (input "foo.txt"))
--   123
--   
--   &gt;&gt;&gt; stdout (grep (suffix "3") (input "foo.txt"))
--   123
--   </pre>
--   
--   You can also build up more sophisticated <a>Shell</a> programs using
--   <a>sh</a> in conjunction with <tt>do</tt> notation:
--   
--   <pre>
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import Turtle
--   
--   main = sh example
--   
--   example = do
--       -- Read in file names from "files1.txt" and "files2.txt"
--       file &lt;- fmap fromText (input "files1.txt" &lt;|&gt; input "files2.txt")
--   
--       -- Stream each file to standard output only if the file exists
--       True &lt;- liftIO (testfile file)
--       line &lt;- input file
--       liftIO (echo line)
--   </pre>
--   
--   See <a>Turtle.Tutorial</a> for an extended tutorial explaining how to
--   use this library in greater detail.
module Turtle.Prelude

-- | Print exactly one line to <tt>stdout</tt>
--   
--   To print more than one line see <a>printf</a>, which also supports
--   formatted output
echo :: MonadIO io => Line -> io ()

-- | Print exactly one line to <tt>stderr</tt>
err :: MonadIO io => Line -> io ()

-- | Read in a line from <tt>stdin</tt>
--   
--   Returns <a>Nothing</a> if at end of input
readline :: MonadIO io => io (Maybe Line)

-- | Read in a file as <a>Text</a>

-- | <i>Deprecated: Use Data.Text.IO.readFile instead</i>
readTextFile :: FilePath -> IO Text

-- | Write out a file as <a>Text</a>

-- | <i>Deprecated: Use Data.Text.IO.writeFile instead</i>
writeTextFile :: FilePath -> Text -> IO ()

-- | Get command line arguments in a list
arguments :: MonadIO io => io [Text]

-- | Set or modify an environment variable
--   
--   Note: This will change the current environment for all of your
--   program's threads since this modifies the global state of the process
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
--   
--   Note: This will change the current directory for all of your program's
--   threads since this modifies the global state of the process
cd :: MonadIO io => FilePath -> io ()

-- | Get the current directory
pwd :: MonadIO io => io FilePath

-- | Get the home directory
home :: MonadIO io => io FilePath

-- | Get the path pointed to by a symlink
readlink :: MonadIO io => FilePath -> io FilePath

-- | Canonicalize a path
realpath :: MonadIO io => FilePath -> io FilePath

-- | Move a file or directory
--   
--   Works if the two paths are on the same filesystem. If not, <tt>mv</tt>
--   will still work when dealing with a regular file, but the operation
--   will not be atomic
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 <tt>mkdir -p</tt>)
--   
--   Does not fail if the directory is present
mktree :: MonadIO io => FilePath -> io ()

-- | Copy a file
cp :: MonadIO io => FilePath -> FilePath -> io ()

-- | Copy a directory tree and preserve symbolic links
cptree :: MonadIO io => FilePath -> FilePath -> io ()

-- | Copy a directory tree and dereference symbolic links
cptreeL :: MonadIO io => FilePath -> FilePath -> io ()

-- | Create a symlink from one <tt>FilePath</tt> to another
symlink :: MonadIO io => FilePath -> FilePath -> io ()

-- | Returns <a>True</a> if the given <a>FilePath</a> is not a symbolic
--   link
--   
--   This comes in handy in conjunction with <a>lsif</a>:
--   
--   <pre>
--   lsif isNotSymbolicLink
--   </pre>
isNotSymbolicLink :: MonadIO io => FilePath -> io Bool

-- | Remove a file
rm :: MonadIO io => FilePath -> io ()

-- | Remove a directory
rmdir :: MonadIO io => FilePath -> io ()

-- | Remove a directory tree (equivalent to <tt>rm -r</tt>)
--   
--   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

-- | Check if a path exists
testpath :: 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

-- | Show the full path of an executable file
which :: MonadIO io => FilePath -> io (Maybe FilePath)

-- | Show all matching executables in PATH, not just the first
whichAll :: FilePath -> Shell FilePath

-- | Sleep for the given duration
--   
--   A numeric literal argument is interpreted as seconds. In other words,
--   <tt>(sleep 2.0)</tt> will sleep for two seconds.
sleep :: MonadIO io => NominalDiffTime -> io ()

-- | Exit with the given exit code
--   
--   An exit code of <tt>0</tt> indicates success
exit :: MonadIO io => ExitCode -> io a

-- | Throw an exception using the provided <a>Text</a> message
die :: MonadIO io => Text -> io a

-- | Analogous to <a>&amp;&amp;</a> in Bash
--   
--   Runs the second command only if the first one returns
--   <a>ExitSuccess</a>
(.&&.) :: Monad m => m ExitCode -> m ExitCode -> m ExitCode
infixr 3 .&&.

-- | Analogous to <a>||</a> in Bash
--   
--   Run the second command only if the first one returns
--   <a>ExitFailure</a>
(.||.) :: Monad m => m ExitCode -> m ExitCode -> m ExitCode
infixr 2 .||.

-- | Acquire a <tt>Managed</tt> read-only <a>Handle</a> from a
--   <a>FilePath</a>
readonly :: MonadManaged managed => FilePath -> managed Handle

-- | Acquire a <tt>Managed</tt> write-only <a>Handle</a> from a
--   <a>FilePath</a>
writeonly :: MonadManaged managed => FilePath -> managed Handle

-- | Acquire a <tt>Managed</tt> append-only <a>Handle</a> from a
--   <a>FilePath</a>
appendonly :: MonadManaged managed => FilePath -> managed Handle

-- | Create a temporary file underneath the given directory
--   
--   Deletes the temporary file when done
--   
--   Note that this provides the <a>Handle</a> of the file in order to
--   avoid a potential race condition from the file being moved or deleted
--   before you have a chance to open the file. The <a>mktempfile</a>
--   function provides a simpler API if you don't need to worry about that
--   possibility.
mktemp :: MonadManaged managed => FilePath -> Text -> managed (FilePath, Handle)

-- | Create a temporary file underneath the given directory
--   
--   Deletes the temporary file when done
mktempfile :: MonadManaged managed => FilePath -> Text -> managed FilePath

-- | Create a temporary directory underneath the given directory
--   
--   Deletes the temporary directory when done
mktempdir :: MonadManaged managed => FilePath -> Text -> managed FilePath

-- | Fork a thread, acquiring an <a>Async</a> value
fork :: MonadManaged managed => IO a -> managed (Async a)

-- | Wait for an <a>Async</a> action to complete
wait :: MonadIO io => Async a -> io a

-- | Change the current directory. Once the current <a>Shell</a> is done,
--   it returns back to the original directory.
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings
--   
--   &gt;&gt;&gt; cd "/"
--   
--   &gt;&gt;&gt; view (pushd "/tmp" &gt;&gt; pwd)
--   FilePath "/tmp"
--   
--   &gt;&gt;&gt; pwd
--   FilePath "/"
--   </pre>
pushd :: MonadManaged managed => FilePath -> managed ()

-- | Read lines of <a>Text</a> from standard input
stdin :: Shell Line

-- | Read lines of <a>Text</a> from a file
input :: FilePath -> Shell Line

-- | Read lines of <a>Text</a> from a <a>Handle</a>
inhandle :: Handle -> Shell Line

-- | Stream lines of <a>Text</a> to standard output
stdout :: MonadIO io => Shell Line -> io ()

-- | Stream lines of <a>Text</a> to a file
output :: MonadIO io => FilePath -> Shell Line -> io ()

-- | Stream lines of <a>Text</a> to a <a>Handle</a>
outhandle :: MonadIO io => Handle -> Shell Line -> io ()

-- | Stream lines of <a>Text</a> to append to a file
append :: MonadIO io => FilePath -> Shell Line -> io ()

-- | Stream lines of <a>Text</a> to standard error
stderr :: MonadIO io => Shell Line -> io ()

-- | Read in a stream's contents strictly
strict :: MonadIO io => Shell Line -> io Text

-- | Stream all immediate children of the given directory, excluding
--   <tt>"."</tt> and <tt>".."</tt>
ls :: FilePath -> Shell FilePath

-- | Stream all recursive descendents of the given directory
--   
--   This skips any directories that fail the supplied predicate
--   
--   <pre>
--   lstree = lsif (\_ -&gt; return True)
--   </pre>
lsif :: (FilePath -> IO Bool) -> FilePath -> Shell FilePath

-- | Stream all recursive descendents of the given directory
lstree :: FilePath -> Shell FilePath

-- | Stream the recursive descendents of a given directory between a given
--   minimum and maximum depth
lsdepth :: Int -> Int -> FilePath -> Shell FilePath

-- | Combine the output of multiple <a>Shell</a>s, in order
cat :: [Shell a] -> Shell a

-- | Keep all lines that match the given <a>Pattern</a>
grep :: Pattern a -> Shell Line -> Shell Line

-- | Keep every <a>Text</a> element that matches the given <a>Pattern</a>
grepText :: Pattern a -> Shell Text -> Shell Text

-- | Replace all occurrences of a <a>Pattern</a> with its <a>Text</a>
--   result
--   
--   <a>sed</a> performs substitution on a line-by-line basis, meaning that
--   substitutions may not span multiple lines. Additionally, substitutions
--   may occur multiple times within the same line, like the behavior of
--   <tt>s/.../.../g</tt>.
--   
--   Warning: Do not use a <a>Pattern</a> that matches the empty string,
--   since it will match an infinite number of times. <a>sed</a> tries to
--   detect such <a>Pattern</a>s and <a>die</a> with an error message if
--   they occur, but this detection is necessarily incomplete.
sed :: Pattern Text -> Shell Line -> Shell Line

-- | Like <a>sed</a>, but the provided substitution must match the
--   beginning of the line
sedPrefix :: Pattern Text -> Shell Line -> Shell Line

-- | Like <a>sed</a>, but the provided substitution must match the end of
--   the line
sedSuffix :: Pattern Text -> Shell Line -> Shell Line

-- | Like <a>sed</a>, but the provided substitution must match the entire
--   line
sedEntire :: Pattern Text -> Shell Line -> Shell Line

-- | Make a `Shell Text -&gt; Shell Text` function work on <a>FilePath</a>s
--   instead. | Ignores any paths which cannot be decoded as valid
--   <a>Text</a>.
onFiles :: (Shell Text -> Shell Text) -> Shell FilePath -> Shell FilePath

-- | Like <a>sed</a>, but operates in place on a <a>FilePath</a> (analogous
--   to <tt>sed -i</tt>)
inplace :: MonadIO io => Pattern Text -> FilePath -> io ()

-- | Like <a>sedPrefix</a>, but operates in place on a <a>FilePath</a>
inplacePrefix :: MonadIO io => Pattern Text -> FilePath -> io ()

-- | Like <a>sedSuffix</a>, but operates in place on a <a>FilePath</a>
inplaceSuffix :: MonadIO io => Pattern Text -> FilePath -> io ()

-- | Like <a>sedEntire</a>, but operates in place on a <a>FilePath</a>
inplaceEntire :: MonadIO io => Pattern Text -> FilePath -> io ()

-- | Update a file in place using a <a>Shell</a> transformation
--   
--   For example, this is used to implement the <tt>inplace*</tt> family of
--   utilities
update :: MonadIO io => (Shell Line -> Shell Line) -> FilePath -> io ()

-- | Search a directory recursively for all files matching the given
--   <a>Pattern</a>
find :: Pattern a -> FilePath -> Shell FilePath

-- | Filter a shell of FilePaths according to a given pattern
findtree :: Pattern a -> Shell FilePath -> Shell FilePath

-- | A Stream of <tt>"y"</tt>s
yes :: Shell Line

-- | Number each element of a <a>Shell</a> (starting at 0)
nl :: Num n => Shell a -> Shell (n, a)

-- | Merge two <a>Shell</a>s together, element-wise
--   
--   If one <a>Shell</a> is longer than the other, the excess elements are
--   truncated
paste :: Shell a -> Shell b -> Shell (a, b)

-- | A <a>Shell</a> that endlessly emits <tt>()</tt>
endless :: Shell ()

-- | Limit a <a>Shell</a> to a fixed number of values
--   
--   NOTE: This is not lazy and will still consume the entire input stream.
--   There is no way to implement a lazy version of this utility.
limit :: Int -> Shell a -> Shell a

-- | Limit a <a>Shell</a> 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 <a>Shell</a>'s output so that repeated runs of the script will
--   reuse the result of previous runs. You must supply a <a>FilePath</a>
--   where the cached result will be stored.
--   
--   The stored result is only reused if the <a>Shell</a> 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

-- | Run a list of IO actions in parallel using fork and wait.
--   
--   <pre>
--   &gt;&gt;&gt; view (parallel [(sleep 3) &gt;&gt; date, date, date])
--   2016-12-01 17:22:10.83296 UTC
--   2016-12-01 17:22:07.829876 UTC
--   2016-12-01 17:22:07.829963 UTC
--   </pre>
parallel :: [IO a] -> Shell a

-- | Returns the result of a <a>Shell</a> that outputs a single line. Note
--   that if no lines / more than 1 line is produced by the Shell, this
--   function will <a>die</a> with an error message.
--   
--   <pre>
--   main = do
--     directory &lt;- single (inshell "pwd" empty)
--     print directory
--   </pre>
single :: MonadIO io => Shell a -> io a

-- | Filter adjacent duplicate elements:
--   
--   <pre>
--   &gt;&gt;&gt; view (uniq (select [1,1,2,1,3]))
--   1
--   2
--   1
--   3
--   </pre>
uniq :: Eq a => Shell a -> Shell a

-- | Filter adjacent duplicates determined after applying the function to
--   the element:
--   
--   <pre>
--   &gt;&gt;&gt; view (uniqOn fst (select [(1,'a'),(1,'b'),(2,'c'),(1,'d'),(3,'e')]))
--   (1,'a')
--   (2,'c')
--   (1,'d')
--   (3,'e')
--   </pre>
uniqOn :: Eq b => (a -> b) -> Shell a -> Shell a

-- | Filter adjacent duplicate elements determined via the given function:
--   
--   <pre>
--   &gt;&gt;&gt; view (uniqBy (==) (select [1,1,2,1,3]))
--   1
--   2
--   1
--   3
--   </pre>
uniqBy :: (a -> a -> Bool) -> Shell a -> Shell a

-- | Return a new <a>Shell</a> that discards duplicates from the input
--   <a>Shell</a>:
--   
--   <pre>
--   &gt;&gt;&gt; view (nub (select [1, 1, 2, 3, 3, 4, 3]))
--   1
--   2
--   3
--   4
--   </pre>
nub :: Ord a => Shell a -> Shell a

-- | Return a new <a>Shell</a> that discards duplicates determined via the
--   given function from the input <a>Shell</a>:
--   
--   <pre>
--   &gt;&gt;&gt; view (nubOn id (select [1, 1, 2, 3, 3, 4, 3]))
--   1
--   2
--   3
--   4
--   </pre>
nubOn :: Ord b => (a -> b) -> Shell a -> Shell a

-- | Return a list of the sorted elements of the given <a>Shell</a>,
--   keeping duplicates:
--   
--   <pre>
--   &gt;&gt;&gt; sort (select [1,4,2,3,3,7])
--   [1,2,3,3,4,7]
--   </pre>
sort :: (Functor io, MonadIO io, Ord a) => Shell a -> io [a]

-- | Return a list of the elements of the given <a>Shell</a>, sorted after
--   applying the given function and keeping duplicates:
--   
--   <pre>
--   &gt;&gt;&gt; sortOn id (select [1,4,2,3,3,7])
--   [1,2,3,3,4,7]
--   </pre>
sortOn :: (Functor io, MonadIO io, Ord b) => (a -> b) -> Shell a -> io [a]

-- | Return a list of the elements of the given <a>Shell</a>, sorted by the
--   given function and keeping duplicates:
--   
--   <pre>
--   &gt;&gt;&gt; sortBy (comparing fst) (select [(1,'a'),(4,'b'),(2,'c'),(3,'d'),(3,'e'),(7,'f')])
--   [(1,'a'),(2,'c'),(3,'d'),(3,'e'),(4,'b'),(7,'f')]
--   </pre>
sortBy :: (Functor io, MonadIO io) => (a -> a -> Ordering) -> Shell a -> io [a]

-- | Group an arbitrary stream of <a>Text</a> into newline-delimited
--   <a>Line</a>s
--   
--   <pre>
--   &gt;&gt;&gt; stdout (toLines ("ABC" &lt;|&gt; "DEF" &lt;|&gt; "GHI")
--   ABCDEFGHI
--   
--   &gt;&gt;&gt; stdout (toLines empty)  -- Note that this always emits at least 1 `Line`
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; stdout (toLines ("ABC\nDEF" &lt;|&gt; "" &lt;|&gt; "GHI\nJKL"))
--   ABC
--   DEFGHI
--   JKL
--   </pre>
toLines :: Shell Text -> Shell Line

-- | Count the number of characters in the stream (like <tt>wc -c</tt>)
--   
--   This uses the convention that the elements of the stream are
--   implicitly ended by newlines that are one character wide
countChars :: Integral n => Fold Line n

-- | Count the number of words in the stream (like <tt>wc -w</tt>)
countWords :: Integral n => Fold Line n

-- | Count the number of lines in the stream (like <tt>wc -l</tt>)
--   
--   This uses the convention that each element of the stream represents
--   one line
countLines :: Integral n => Fold Line n

-- | Split a line into chunks delimited by the given <a>Pattern</a>
cut :: Pattern a -> Text -> [Text]

-- | Run a command using <tt>execvp</tt>, retrieving the exit code
--   
--   The command inherits <tt>stdout</tt> and <tt>stderr</tt> for the
--   current process
proc :: MonadIO io => Text -> [Text] -> Shell Line -> io ExitCode

-- | Run a command line using the shell, retrieving the exit code
--   
--   This command is more powerful than <a>proc</a>, but highly vulnerable
--   to code injection if you template the command line with untrusted
--   input
--   
--   The command inherits <tt>stdout</tt> and <tt>stderr</tt> for the
--   current process
shell :: MonadIO io => Text -> Shell Line -> io ExitCode

-- | This function is identical to <a>proc</a> except this throws
--   <a>ProcFailed</a> for non-zero exit codes
procs :: MonadIO io => Text -> [Text] -> Shell Line -> io ()

-- | This function is identical to <a>shell</a> except this throws
--   <a>ShellFailed</a> for non-zero exit codes
shells :: MonadIO io => Text -> Shell Line -> io ()

-- | Run a command using <tt>execvp</tt>, streaming <tt>stdout</tt> as
--   lines of <a>Text</a>
--   
--   The command inherits <tt>stderr</tt> for the current process
inproc :: Text -> [Text] -> Shell Line -> Shell Line

-- | Run a command line using the shell, streaming <tt>stdout</tt> as lines
--   of <a>Text</a>
--   
--   This command is more powerful than <a>inproc</a>, but highly
--   vulnerable to code injection if you template the command line with
--   untrusted input
--   
--   The command inherits <tt>stderr</tt> for the current process
--   
--   Throws an <a>ExitCode</a> exception if the command returns a non-zero
--   exit code
inshell :: Text -> Shell Line -> Shell Line

-- | Run a command using the shell, streaming <tt>stdout</tt> and
--   <tt>stderr</tt> as lines of <a>Text</a>. Lines from <tt>stdout</tt>
--   are wrapped in <a>Right</a> and lines from <tt>stderr</tt> are wrapped
--   in <a>Left</a>.
--   
--   Throws an <a>ExitCode</a> exception if the command returns a non-zero
--   exit code
inprocWithErr :: Text -> [Text] -> Shell Line -> Shell (Either Line Line)

-- | Run a command line using the shell, streaming <tt>stdout</tt> and
--   <tt>stderr</tt> as lines of <a>Text</a>. Lines from <tt>stdout</tt>
--   are wrapped in <a>Right</a> and lines from <tt>stderr</tt> are wrapped
--   in <a>Left</a>.
--   
--   This command is more powerful than <a>inprocWithErr</a>, but highly
--   vulnerable to code injection if you template the command line with
--   untrusted input
--   
--   Throws an <a>ExitCode</a> exception if the command returns a non-zero
--   exit code
inshellWithErr :: Text -> Shell Line -> Shell (Either Line Line)

-- | Run a command using <tt>execvp</tt>, retrieving the exit code and
--   stdout as a non-lazy blob of Text
--   
--   The command inherits <tt>stderr</tt> for the current process
procStrict :: MonadIO io => Text -> [Text] -> Shell Line -> 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 <a>proc</a>, but highly vulnerable
--   to code injection if you template the command line with untrusted
--   input
--   
--   The command inherits <tt>stderr</tt> for the current process
shellStrict :: MonadIO io => Text -> Shell Line -> io (ExitCode, Text)

-- | Run a command using <tt>execvp</tt>, retrieving the exit code, stdout,
--   and stderr as a non-lazy blob of Text
procStrictWithErr :: MonadIO io => Text -> [Text] -> Shell Line -> io (ExitCode, Text, Text)

-- | Run a command line using the shell, retrieving the exit code, stdout,
--   and stderr as a non-lazy blob of Text
--   
--   This command is more powerful than <a>proc</a>, but highly vulnerable
--   to code injection if you template the command line with untrusted
--   input
shellStrictWithErr :: MonadIO io => Text -> Shell Line -> io (ExitCode, Text, Text)

-- | <a>system</a> generalizes <a>shell</a> and <a>proc</a> by allowing you
--   to supply your own custom <tt>CreateProcess</tt>. This is for advanced
--   users who feel comfortable using the lower-level <tt>process</tt> API
system :: MonadIO io => CreateProcess -> Shell Line -> io ExitCode

-- | <a>stream</a> generalizes <a>inproc</a> and <a>inshell</a> by allowing
--   you to supply your own custom <tt>CreateProcess</tt>. This is for
--   advanced users who feel comfortable using the lower-level
--   <tt>process</tt> API
--   
--   Throws an <a>ExitCode</a> exception if the command returns a non-zero
--   exit code
stream :: CreateProcess -> Shell Line -> Shell Line

-- | <a>streamWithErr</a> generalizes <a>inprocWithErr</a> and
--   <a>inshellWithErr</a> by allowing you to supply your own custom
--   <tt>CreateProcess</tt>. This is for advanced users who feel
--   comfortable using the lower-level <tt>process</tt> API
--   
--   Throws an <a>ExitCode</a> exception if the command returns a non-zero
--   exit code
streamWithErr :: CreateProcess -> Shell Line -> Shell (Either Line Line)

-- | <a>systemStrict</a> generalizes <a>shellStrict</a> and
--   <a>procStrict</a> by allowing you to supply your own custom
--   <tt>CreateProcess</tt>. This is for advanced users who feel
--   comfortable using the lower-level <tt>process</tt> API
systemStrict :: MonadIO io => CreateProcess -> Shell Line -> io (ExitCode, Text)

-- | <a>systemStrictWithErr</a> generalizes <a>shellStrictWithErr</a> and
--   <a>procStrictWithErr</a> by allowing you to supply your own custom
--   <tt>CreateProcess</tt>. This is for advanced users who feel
--   comfortable using the lower-level <tt>process</tt> API
systemStrictWithErr :: MonadIO io => CreateProcess -> Shell Line -> io (ExitCode, Text, Text)

-- | This type is the same as
--   <tt><a>System.Directory</a>.<a>Permissions</a></tt> type except
--   combining the <a>executable</a> and <a>searchable</a> fields into a
--   single <a>executable</a> field for consistency with the Unix
--   <tt>chmod</tt>. This simplification is still entirely consistent with
--   the behavior of <a>System.Directory</a>, which treats the two fields
--   as interchangeable.
data Permissions
Permissions :: Bool -> Bool -> Bool -> Permissions
[_readable] :: Permissions -> Bool
[_writable] :: Permissions -> Bool
[_executable] :: Permissions -> Bool

-- | Update a file or directory's user permissions
--   
--   <pre>
--   chmod rwo         "foo.txt"  -- chmod u=rw foo.txt
--   chmod executable  "foo.txt"  -- chmod u+x foo.txt
--   chmod nonwritable "foo.txt"  -- chmod u-w foo.txt
--   </pre>
--   
--   The meaning of each permission is:
--   
--   <ul>
--   <li><a>readable</a> (<tt>+r</tt> for short): For files, determines
--   whether you can read from that file (such as with <a>input</a>). For
--   directories, determines whether or not you can list the directory
--   contents (such as with <a>ls</a>). Note: if a directory is not
--   readable then <a>ls</a> will stream an empty list of contents</li>
--   <li><a>writable</a> (<tt>+w</tt> for short): For files, determines
--   whether you can write to that file (such as with <a>output</a>). For
--   directories, determines whether you can create a new file underneath
--   that directory.</li>
--   <li><a>executable</a> (<tt>+x</tt> for short): For files, determines
--   whether or not that file is executable (such as with <a>proc</a>). For
--   directories, determines whether or not you can read or execute files
--   underneath that directory (such as with <a>input</a> or
--   <a>proc</a>)</li>
--   </ul>
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 ()

-- | Copy a file or directory's permissions (analogous to <tt>chmod
--   --reference</tt>)
copymod :: MonadIO io => FilePath -> FilePath -> io ()

-- | <pre>
--   +r
--   </pre>
readable :: Permissions -> Permissions

-- | <pre>
--   -r
--   </pre>
nonreadable :: Permissions -> Permissions

-- | <pre>
--   +w
--   </pre>
writable :: Permissions -> Permissions

-- | <pre>
--   -w
--   </pre>
nonwritable :: Permissions -> Permissions

-- | <pre>
--   +x
--   </pre>
executable :: Permissions -> Permissions

-- | <pre>
--   -x
--   </pre>
nonexecutable :: Permissions -> Permissions

-- | <pre>
--   -r -w -x
--   </pre>
ooo :: Permissions -> Permissions

-- | <pre>
--   +r -w -x
--   </pre>
roo :: Permissions -> Permissions

-- | <pre>
--   -r +w -x
--   </pre>
owo :: Permissions -> Permissions

-- | <pre>
--   -r -w +x
--   </pre>
oox :: Permissions -> Permissions

-- | <pre>
--   +r +w -x
--   </pre>
rwo :: Permissions -> Permissions

-- | <pre>
--   +r -w +x
--   </pre>
rox :: Permissions -> Permissions

-- | <pre>
--   -r +w +x
--   </pre>
owx :: Permissions -> Permissions

-- | <pre>
--   +r +w +x
--   </pre>
rwx :: 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 <a>kilobytes</a>
--   
--   The <a>Num</a> instance for <a>Size</a> interprets numeric literals as
--   bytes
data Size

-- | Construct a <a>Size</a> from an integer in bytes
--   
--   <pre>
--   &gt;&gt;&gt; format sz (B 42)
--   "42 B"
--   </pre>
pattern B :: Integral n => n -> Size

-- | Construct a <a>Size</a> from an integer in kilobytes
--   
--   <pre>
--   &gt;&gt;&gt; format sz (KB 42)
--   "42.0 KB"
--   
--   &gt;&gt;&gt; let B n = KB 1 in n
--   1000
--   </pre>
pattern KB :: Integral n => n -> Size

-- | Construct a <a>Size</a> from an integer in megabytes
--   
--   <pre>
--   &gt;&gt;&gt; format sz (MB 42)
--   "42.0 MB"
--   
--   &gt;&gt;&gt; let KB n = MB 1 in n
--   1000
--   </pre>
pattern MB :: Integral n => n -> Size

-- | Construct a <a>Size</a> from an integer in gigabytes
--   
--   <pre>
--   &gt;&gt;&gt; format sz (GB 42)
--   "42.0 GB"
--   
--   &gt;&gt;&gt; let MB n = GB 1 in n
--   1000
--   </pre>
pattern GB :: Integral n => n -> Size

-- | Construct a <a>Size</a> from an integer in terabytes
--   
--   <pre>
--   &gt;&gt;&gt; format sz (TB 42)
--   "42.0 TB"
--   
--   &gt;&gt;&gt; let GB n = TB 1 in n
--   1000
--   </pre>
pattern TB :: Integral n => n -> Size

-- | Construct a <a>Size</a> from an integer in kibibytes
--   
--   <pre>
--   &gt;&gt;&gt; format sz (KiB 42)
--   "43.8 KB"
--   
--   &gt;&gt;&gt; let B n = KiB 1 in n
--   1024
--   </pre>
pattern KiB :: Integral n => n -> Size

-- | Construct a <a>Size</a> from an integer in mebibytes
--   
--   <pre>
--   &gt;&gt;&gt; format sz (MiB 42)
--   "44.40 MB"
--   
--   &gt;&gt;&gt; let KiB n = MiB 1 in n
--   1024
--   </pre>
pattern MiB :: Integral n => n -> Size

-- | Construct a <a>Size</a> from an integer in gibibytes
--   
--   <pre>
--   &gt;&gt;&gt; format sz (GiB 42)
--   "45.97 GB"
--   
--   &gt;&gt;&gt; let MiB n = GiB 1 in n
--   1024
--   </pre>
pattern GiB :: Integral n => n -> Size

-- | Construct a <a>Size</a> from an integer in tebibytes
--   
--   <pre>
--   &gt;&gt;&gt; format sz (TiB 42)
--   "46.179 TB"
--   
--   &gt;&gt;&gt; let GiB n = TiB 1 in n
--   1024
--   </pre>
pattern TiB :: Integral n => n -> Size

-- | <a>Format</a> a <a>Size</a> using a human readable representation
--   
--   <pre>
--   &gt;&gt;&gt; format sz 42
--   "42 B"
--   
--   &gt;&gt;&gt; format sz 2309
--   "2.309 KB"
--   
--   &gt;&gt;&gt; format sz 949203
--   "949.203 KB"
--   
--   &gt;&gt;&gt; format sz 1600000000
--   "1.600 GB"
--   
--   &gt;&gt;&gt; format sz 999999999999999999
--   "999999.999 TB"
--   </pre>
sz :: Format r (Size -> r)

-- | Extract a size in bytes
bytes :: Integral n => Size -> n

-- | <pre>
--   1 kilobyte = 1000 bytes
--   </pre>
kilobytes :: Integral n => Size -> n

-- | <pre>
--   1 megabyte = 1000 kilobytes
--   </pre>
megabytes :: Integral n => Size -> n

-- | <pre>
--   1 gigabyte = 1000 megabytes
--   </pre>
gigabytes :: Integral n => Size -> n

-- | <pre>
--   1 terabyte = 1000 gigabytes
--   </pre>
terabytes :: Integral n => Size -> n

-- | <pre>
--   1 kibibyte = 1024 bytes
--   </pre>
kibibytes :: Integral n => Size -> n

-- | <pre>
--   1 mebibyte = 1024 kibibytes
--   </pre>
mebibytes :: Integral n => Size -> n

-- | <pre>
--   1 gibibyte = 1024 mebibytes
--   </pre>
gibibytes :: Integral n => Size -> n

-- | <pre>
--   1 tebibyte = 1024 gibibytes
--   </pre>
tebibytes :: Integral n => Size -> n
data () => FileStatus

-- | Get the status of a file
stat :: MonadIO io => FilePath -> io FileStatus

-- | Get the status of a file, but don't follow symbolic links
lstat :: MonadIO io => FilePath -> io FileStatus

-- | Size of the file in bytes. Does not follow symlinks
fileSize :: FileStatus -> Size

-- | Time of last access
accessTime :: FileStatus -> POSIXTime

-- | Time of last modification
modificationTime :: FileStatus -> POSIXTime

-- | Time of last status change (i.e. owner, group, link count, mode, etc.)
statusChangeTime :: FileStatus -> POSIXTime
isBlockDevice :: FileStatus -> Bool
isCharacterDevice :: FileStatus -> Bool
isNamedPipe :: FileStatus -> Bool
isRegularFile :: FileStatus -> Bool
isDirectory :: FileStatus -> Bool
isSymbolicLink :: FileStatus -> Bool
isSocket :: FileStatus -> Bool

-- | Check if a file was last modified after a given timestamp
cmin :: MonadIO io => UTCTime -> FilePath -> io Bool

-- | Check if a file was last modified before a given timestamp
cmax :: MonadIO io => UTCTime -> FilePath -> io Bool
data WithHeader a

-- | The first line with the header
Header :: a -> WithHeader a

-- | Every other line: 1st element is header, 2nd element is original row
Row :: a -> a -> WithHeader a
header :: Shell a -> Shell (WithHeader a)
data ProcFailed
ProcFailed :: Text -> [Text] -> ExitCode -> ProcFailed
[procCommand] :: ProcFailed -> Text
[procArguments] :: ProcFailed -> [Text]
[procExitCode] :: ProcFailed -> ExitCode
data ShellFailed
ShellFailed :: Text -> ExitCode -> ShellFailed
[shellCommandLine] :: ShellFailed -> Text
[shellExitCode] :: ShellFailed -> ExitCode
instance GHC.Show.Show Turtle.Prelude.ProcFailed
instance GHC.Show.Show Turtle.Prelude.ShellFailed
instance GHC.Show.Show Turtle.Prelude.Permissions
instance GHC.Classes.Ord Turtle.Prelude.Permissions
instance GHC.Read.Read Turtle.Prelude.Permissions
instance GHC.Classes.Eq Turtle.Prelude.Permissions
instance GHC.Num.Num Turtle.Prelude.Size
instance GHC.Classes.Ord Turtle.Prelude.Size
instance GHC.Classes.Eq Turtle.Prelude.Size
instance GHC.Show.Show a => GHC.Show.Show (Turtle.Prelude.WithHeader a)
instance GHC.Show.Show Turtle.Prelude.Size
instance GHC.Exception.Type.Exception Turtle.Prelude.ShellFailed
instance GHC.Exception.Type.Exception Turtle.Prelude.ProcFailed


-- | This module provides <a>ByteString</a> analogs of several utilities in
--   <a>Turtle.Prelude</a>. The main difference is that the chunks of bytes
--   read by these utilities are not necessarily aligned to line
--   boundaries.
module Turtle.Bytes

-- | Read chunks of bytes from standard input
--   
--   The chunks are not necessarily aligned to line boundaries
stdin :: Shell ByteString

-- | Read chunks of bytes from a file
--   
--   The chunks are not necessarily aligned to line boundaries
input :: FilePath -> Shell ByteString

-- | Read chunks of bytes from a <a>Handle</a>
--   
--   The chunks are not necessarily aligned to line boundaries
inhandle :: Handle -> Shell ByteString

-- | Stream chunks of bytes to standard output
--   
--   The chunks are not necessarily aligned to line boundaries
stdout :: MonadIO io => Shell ByteString -> io ()

-- | Stream chunks of bytes to a file
--   
--   The chunks do not need to be aligned to line boundaries
output :: MonadIO io => FilePath -> Shell ByteString -> io ()

-- | Stream chunks of bytes to a <a>Handle</a>
--   
--   The chunks do not need to be aligned to line boundaries
outhandle :: MonadIO io => Handle -> Shell ByteString -> io ()

-- | Append chunks of bytes to append to a file
--   
--   The chunks do not need to be aligned to line boundaries
append :: MonadIO io => FilePath -> Shell ByteString -> io ()

-- | Stream chunks of bytes to standard error
--   
--   The chunks do not need to be aligned to line boundaries
stderr :: MonadIO io => Shell ByteString -> io ()

-- | Read in a stream's contents strictly
strict :: MonadIO io => Shell ByteString -> io ByteString

-- | Compress a stream using <tt>zlib</tt>
--   
--   Note that this can decompress streams that are the concatenation of
--   multiple compressed streams (just like <tt>gzip</tt>)
--   
--   <pre>
--   &gt;&gt;&gt; let compressed = select [ "ABC", "DEF" ] &amp; compress 0 defaultWindowBits
--   
--   &gt;&gt;&gt; compressed &amp; decompress defaultWindowBits &amp; view
--   "ABCDEF"
--   
--   &gt;&gt;&gt; (compressed &lt;|&gt; compressed) &amp; decompress defaultWindowBits &amp; view
--   "ABCDEF"
--   "ABCDEF"
--   </pre>
compress :: Int -> WindowBits -> Shell ByteString -> Shell ByteString

-- | Decompress a stream using <tt>zlib</tt> (just like the <tt>gzip</tt>
--   command)
decompress :: WindowBits -> Shell ByteString -> Shell ByteString
data () => WindowBits
WindowBits :: Int -> WindowBits
defaultWindowBits :: WindowBits

-- | Encode a stream of bytes as UTF8 <a>Text</a>
fromUTF8 :: Shell Text -> Shell ByteString

-- | Decode a stream of bytes as UTF8 <a>Text</a>
--   
--   NOTE: This function will throw a pure exception (i.e. an <a>error</a>)
--   if UTF8 decoding fails (mainly due to limitations in the <tt>text</tt>
--   package's stream decoding API)
toUTF8 :: Shell ByteString -> Shell Text

-- | Run a command using <tt>execvp</tt>, retrieving the exit code
--   
--   The command inherits <tt>stdout</tt> and <tt>stderr</tt> for the
--   current process
proc :: MonadIO io => Text -> [Text] -> Shell ByteString -> io ExitCode

-- | Run a command line using the shell, retrieving the exit code
--   
--   This command is more powerful than <a>proc</a>, but highly vulnerable
--   to code injection if you template the command line with untrusted
--   input
--   
--   The command inherits <tt>stdout</tt> and <tt>stderr</tt> for the
--   current process
shell :: MonadIO io => Text -> Shell ByteString -> io ExitCode

-- | This function is identical to <a>proc</a> except this throws
--   <a>ProcFailed</a> for non-zero exit codes
procs :: MonadIO io => Text -> [Text] -> Shell ByteString -> io ()

-- | This function is identical to <a>shell</a> except this throws
--   <a>ShellFailed</a> for non-zero exit codes
shells :: MonadIO io => Text -> Shell ByteString -> io ()

-- | Run a command using <tt>execvp</tt>, streaming <tt>stdout</tt> as
--   chunks of <a>ByteString</a>
--   
--   The command inherits <tt>stderr</tt> for the current process
inproc :: Text -> [Text] -> Shell ByteString -> Shell ByteString

-- | Run a command line using the shell, streaming <tt>stdout</tt> as
--   chunks of <a>ByteString</a>
--   
--   This command is more powerful than <a>inproc</a>, but highly
--   vulnerable to code injection if you template the command line with
--   untrusted input
--   
--   The command inherits <tt>stderr</tt> for the current process
inshell :: Text -> Shell ByteString -> Shell ByteString

-- | Run a command using the shell, streaming <tt>stdout</tt> and
--   <tt>stderr</tt> as chunks of <a>ByteString</a>. Chunks from
--   <tt>stdout</tt> are wrapped in <a>Right</a> and chunks from
--   <tt>stderr</tt> are wrapped in <a>Left</a>.
--   
--   Throws an <a>ExitCode</a> exception if the command returns a non-zero
--   exit code
inprocWithErr :: Text -> [Text] -> Shell ByteString -> Shell (Either ByteString ByteString)

-- | Run a command line using the shell, streaming <tt>stdout</tt> and
--   <tt>stderr</tt> as chunks of <a>ByteString</a>. Chunks from
--   <tt>stdout</tt> are wrapped in <a>Right</a> and chunks from
--   <tt>stderr</tt> are wrapped in <a>Left</a>.
--   
--   This command is more powerful than <a>inprocWithErr</a>, but highly
--   vulnerable to code injection if you template the command line with
--   untrusted input
--   
--   Throws an <a>ExitCode</a> exception if the command returns a non-zero
--   exit code
inshellWithErr :: Text -> Shell ByteString -> Shell (Either ByteString ByteString)

-- | Run a command using <tt>execvp</tt>, retrieving the exit code and
--   stdout as a non-lazy blob of Text
--   
--   The command inherits <tt>stderr</tt> for the current process
procStrict :: MonadIO io => Text -> [Text] -> Shell ByteString -> io (ExitCode, ByteString)

-- | 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 <a>proc</a>, but highly vulnerable
--   to code injection if you template the command line with untrusted
--   input
--   
--   The command inherits <tt>stderr</tt> for the current process
shellStrict :: MonadIO io => Text -> Shell ByteString -> io (ExitCode, ByteString)

-- | Run a command using <tt>execvp</tt>, retrieving the exit code, stdout,
--   and stderr as a non-lazy blob of Text
procStrictWithErr :: MonadIO io => Text -> [Text] -> Shell ByteString -> io (ExitCode, ByteString, ByteString)

-- | Run a command line using the shell, retrieving the exit code, stdout,
--   and stderr as a non-lazy blob of Text
--   
--   This command is more powerful than <a>proc</a>, but highly vulnerable
--   to code injection if you template the command line with untrusted
--   input
shellStrictWithErr :: MonadIO io => Text -> Shell ByteString -> io (ExitCode, ByteString, ByteString)

-- | <a>system</a> generalizes <a>shell</a> and <a>proc</a> by allowing you
--   to supply your own custom <tt>CreateProcess</tt>. This is for advanced
--   users who feel comfortable using the lower-level <tt>process</tt> API
system :: MonadIO io => CreateProcess -> Shell ByteString -> io ExitCode

-- | <a>stream</a> generalizes <a>inproc</a> and <a>inshell</a> by allowing
--   you to supply your own custom <tt>CreateProcess</tt>. This is for
--   advanced users who feel comfortable using the lower-level
--   <tt>process</tt> API
--   
--   Throws an <a>ExitCode</a> exception if the command returns a non-zero
--   exit code
stream :: CreateProcess -> Shell ByteString -> Shell ByteString

-- | <a>streamWithErr</a> generalizes <a>inprocWithErr</a> and
--   <a>inshellWithErr</a> by allowing you to supply your own custom
--   <tt>CreateProcess</tt>. This is for advanced users who feel
--   comfortable using the lower-level <tt>process</tt> API
--   
--   Throws an <a>ExitCode</a> exception if the command returns a non-zero
--   exit code
streamWithErr :: CreateProcess -> Shell ByteString -> Shell (Either ByteString ByteString)

-- | <a>systemStrict</a> generalizes <a>shellStrict</a> and
--   <a>procStrict</a> by allowing you to supply your own custom
--   <tt>CreateProcess</tt>. This is for advanced users who feel
--   comfortable using the lower-level <tt>process</tt> API
systemStrict :: MonadIO io => CreateProcess -> Shell ByteString -> io (ExitCode, ByteString)

-- | <a>systemStrictWithErr</a> generalizes <a>shellStrictWithErr</a> and
--   <a>procStrictWithErr</a> by allowing you to supply your own custom
--   <tt>CreateProcess</tt>. This is for advanced users who feel
--   comfortable using the lower-level <tt>process</tt> API
systemStrictWithErr :: MonadIO io => CreateProcess -> Shell ByteString -> io (ExitCode, ByteString, ByteString)


-- | See <a>Turtle.Tutorial</a> to learn how to use this library or
--   <a>Turtle.Prelude</a> for a quick-start guide.
--   
--   Here is the recommended way to import this library:
--   
--   <pre>
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   import Turtle
--   import Prelude hiding (FilePath)
--   </pre>
--   
--   This module re-exports the rest of the library and also re-exports
--   useful modules from <tt>base</tt>:
--   
--   <a>Turtle.Format</a> provides type-safe string formatting
--   
--   <a>Turtle.Pattern</a> provides <a>Pattern</a>s, which are like more
--   powerful regular expressions
--   
--   <a>Turtle.Shell</a> provides a <a>Shell</a> abstraction for building
--   streaming, exception-safe pipelines
--   
--   <a>Turtle.Prelude</a> provides a library of Unix-like utilities to get
--   you started with basic shell-like programming within Haskell
--   
--   <a>Control.Applicative</a> provides two classes:
--   
--   <ul>
--   <li><a>Applicative</a>, which works with <a>Fold</a>, <a>Pattern</a>,
--   <a>Managed</a>, and <a>Shell</a></li>
--   <li><a>Alternative</a>, which works with <a>Pattern</a> and
--   <a>Shell</a></li>
--   </ul>
--   
--   <a>Control.Monad</a> provides two classes:
--   
--   <ul>
--   <li><a>Monad</a>, which works with <a>Pattern</a>, <a>Managed</a> and
--   <a>Shell</a></li>
--   <li><a>MonadPlus</a>, which works with <a>Pattern</a> and
--   <a>Shell</a></li>
--   </ul>
--   
--   <a>Control.Monad.IO.Class</a> provides one class:
--   
--   <ul>
--   <li><a>MonadIO</a>, which works with <a>Managed</a> and
--   <a>Shell</a></li>
--   </ul>
--   
--   <a>Data.Monoid</a> provides one class:
--   
--   <ul>
--   <li><a>Monoid</a>, which works with <a>Fold</a>, <a>Pattern</a>,
--   <a>Managed</a>, and <a>Shell</a></li>
--   </ul>
--   
--   <a>Control.Monad.Managed.Safe</a> provides <a>Managed</a> resources
--   
--   Additionally, you might also want to import the following modules
--   qualified:
--   
--   <ul>
--   <li><a>Options.Applicative</a> from <tt>optparse-applicative</tt> for
--   command-line option parsing</li>
--   <li><a>Control.Foldl</a> (for predefined folds)</li>
--   <li><a>Control.Foldl.Text</a> (for <a>Text</a>-specific folds)</li>
--   <li><a>Data.Text</a> (for <a>Text</a>-manipulation utilities)</li>
--   <li><a>Data.Text.IO</a> (for reading and writing <a>Text</a>)</li>
--   </ul>
module Turtle
class Functor f => Applicative (f :: Type -> Type)
pure :: Applicative f => a -> f a
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
(*>) :: Applicative f => f a -> f b -> f b
(<*) :: Applicative f => f a -> f b -> f a
class Applicative f => Alternative (f :: Type -> Type)
empty :: Alternative f => f a
(<|>) :: Alternative f => f a -> f a -> f a
some :: Alternative f => f a -> f [a]
many :: Alternative f => f a -> f [a]
(<$>) :: Functor f => (a -> b) -> f a -> f b
optional :: Alternative f => f a -> f (Maybe a)
class (Alternative m, Monad m) => MonadPlus (m :: Type -> Type)
mzero :: MonadPlus m => m a
mplus :: MonadPlus m => m a -> m a -> m a
forever :: Applicative f => f a -> f b
void :: Functor f => f a -> f ()
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
join :: Monad m => m (m a) -> m a
msum :: (Foldable t, MonadPlus m) => t (m a) -> m a
mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a
replicateM_ :: Applicative m => Int -> m a -> m ()
guard :: Alternative f => Bool -> f ()
when :: Applicative f => Bool -> f () -> f ()
unless :: Applicative f => Bool -> f () -> f ()
class Monad m => MonadIO (m :: Type -> Type)
liftIO :: MonadIO m => IO a -> m a
class Semigroup a => Monoid a
mempty :: Monoid a => a
mappend :: Monoid a => a -> a -> a
mconcat :: Monoid a => [a] -> a
(<>) :: Semigroup a => a -> a -> a
data () => Managed a
managed :: MonadManaged m => (forall r. () => (a -> IO r) -> IO r) -> m a
runManaged :: Managed () -> IO ()
with :: Managed a -> (a -> IO r) -> IO r
type FilePath = String
dropExtension :: FilePath -> FilePath
hasExtension :: FilePath -> Bool
isAbsolute :: FilePath -> Bool
isRelative :: FilePath -> Bool
(</>) :: FilePath -> FilePath -> FilePath
(<.>) :: FilePath -> String -> FilePath

-- | Retrieves the <a>FilePath</a>'s directory
directory :: FilePath -> FilePath

-- | Retrieves the <a>FilePath</a>'s root
root :: FilePath -> FilePath

-- | Retrieves the <a>FilePath</a>'s parent directory
parent :: FilePath -> FilePath

-- | Retrieves the <a>FilePath</a>'s filename component
filename :: FilePath -> FilePath

-- | Retrieve a <a>FilePath</a>'s directory name
dirname :: FilePath -> FilePath

-- | Retrieve a <a>FilePath</a>'s basename component
basename :: FilePath -> String

-- | Test whether a path is absolute

-- | <i>Deprecated: Use System.FilePath.isAbsolute instead</i>
absolute :: FilePath -> Bool

-- | Test whether a path is relative

-- | <i>Deprecated: Use System.FilePath.isRelative instead</i>
relative :: FilePath -> Bool

-- | Find the greatest common prefix between a list of <a>FilePath</a>s
commonPrefix :: [FilePath] -> FilePath

-- | Remove a prefix from a path
stripPrefix :: FilePath -> FilePath -> Maybe FilePath

-- | Normalise a path

-- | <i>Deprecated: Use System.FilePath.normalise instead</i>
collapse :: FilePath -> FilePath

-- | Split a <a>FilePath</a> into its components
splitDirectories :: FilePath -> [FilePath]

-- | Get a <a>FilePath</a>'s last extension, or <a>Nothing</a> if it has no
--   extension
extension :: FilePath -> Maybe String

-- | Split a <a>FilePath</a> on its extension
splitExtension :: FilePath -> (String, Maybe String)

-- | Split a <a>FilePath</a> on its extensions
splitExtensions :: FilePath -> (String, [String])

-- | Convert a <a>FilePath</a> to human-readable <a>Text</a>
--   
--   Note that even though the type says <a>Either</a> this utility
--   actually always succeeds and returns a <a>Right</a> value. The only
--   reason for the <a>Either</a> is compatibility with the old type from
--   the <tt>system-filepath</tt> package.

-- | <i>Deprecated: Use Data.Text.pack instead</i>
toText :: FilePath -> Either Text Text

-- | Convert <a>Text</a> to a <a>FilePath</a>

-- | <i>Deprecated: Use Data.Text.unpack instead</i>
fromText :: Text -> FilePath

-- | Convert a <a>FilePath</a> to a <a>String</a>

-- | <i>Deprecated: Use id instead</i>
encodeString :: FilePath -> String

-- | Convert a <a>String</a> to a <a>FilePath</a>

-- | <i>Deprecated: Use id instead</i>
decodeString :: String -> FilePath
data () => Fold a b
Fold :: (x -> a -> x) -> x -> (x -> b) -> Fold a b
data () => FoldM (m :: Type -> Type) a b
FoldM :: (x -> a -> m x) -> m x -> (x -> m b) -> FoldM (m :: Type -> Type) a b
data () => Text
data () => UTCTime
data () => NominalDiffTime
data () => Handle
data () => ExitCode
ExitSuccess :: ExitCode
ExitFailure :: Int -> ExitCode
class () => IsString a
fromString :: IsString a => String -> a
(&) :: a -> (a -> b) -> b
(<&>) :: Functor f => f a -> (a -> b) -> f b


-- | Use <tt>turtle</tt> if you want to write light-weight and maintainable
--   shell scripts.
--   
--   <tt>turtle</tt> embeds shell scripting directly within Haskell for
--   three main reasons:
--   
--   <ul>
--   <li>Haskell code is easy to refactor and maintain because the language
--   is statically typed</li>
--   <li>Haskell is syntactically lightweight, thanks to global type
--   inference</li>
--   <li>Haskell programs can be type-checked and interpreted very rapidly
--   (&lt; 1 second)</li>
--   </ul>
--   
--   These features make Haskell ideal for scripting, particularly for
--   replacing large and unwieldy Bash scripts.
--   
--   This tutorial introduces how to use the <tt>turtle</tt> library to
--   write Haskell scripts. This assumes no prior knowledge of Haskell, but
--   does assume prior knowledge of Bash or a similar shell scripting
--   language.
--   
--   If you are already proficient with Haskell, then you can get quickly
--   up to speed by reading the Quick Start guide at the top of
--   <a>Turtle.Prelude</a>.
--   
--   If you are on Windows, the easiest way to follow along is to install
--   <a>Git for Windows</a> and use the Git Bash program that it installs
--   to get a fully featured Unix-like environment.
--   
--   For all operating systems, the recommended way to compile and run the
--   following examples is to download the <tt>stack</tt> package
--   management tool by following the instructions here:
--   
--   <a>https://github.com/commercialhaskell/stack</a>
--   
--   ... and then run the following instruction anywhere outside of a
--   Haskell project:
--   
--   <pre>
--   $ stack install turtle
--   </pre>
--   
--   This tutorial will mostly focus on using Haskell as a scripting
--   language. The first two lines of each script below contain boilerplate
--   instructions so that <tt>stack</tt> will load and run the script. This
--   helps ensure that a script will run on any computer that has a
--   <tt>stack</tt> executable, as <tt>stack</tt> can install a Haskell
--   compiler if one is not already present. If you are curious about how
--   these two lines work, they are described here:
--   
--   
--   <a>https://github.com/commercialhaskell/stack/blob/master/doc/GUIDE.md#script-interpreter</a>
--   
--   If you want to make a Windows script independently executable outside
--   of a Git Bash environment, you can either (A) compile the script into
--   an executable or (B) run these two commands from a <tt>cmd</tt> shell
--   with administrator privileges to make all <tt>*.hs</tt> scripts
--   executable:
--   
--   <pre>
--   assoc .hs=Haskell
--   ftype Haskell="C:\path\to\stack.exe" "%1" %*
--   </pre>
module Turtle.Tutorial
