*              ! " # $ % & ' ( ) *+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl m n o p qrstuvwxyz{|}~ Safe P#Evaluates the value before calling .#Evaluates the value before calling .  Safef %Update the first component of a pair. #first succ (1,"test") == (2,"test")&Update the second component of a pair. 'second reverse (1,"test") == (1,"tset")iGiven two functions, apply one to the first component and one to the second. A specialised version of . +(succ *** reverse) (1,"test") == (2,"tset")aGiven two functions, apply both to a single argument to form a pair. A specialised version of . (succ &&& pred) 1 == (2,0) %Duplicate a single value into a pair. dupe 12 == (12, 12)!5Apply a single function to both components of a pair. both succ (1,2) == (2,3)" Extract the  of a triple.# Extract the  of a triple.$&Extract the final element of a triple. !"#$  !"#$33Safe &'0STVh+   Safe8%2Show a number to a fixed number of decimal places. @showDP 4 pi == "3.1416" showDP 0 pi == "3" showDP 2 3 == "3.00"&;Specialised numeric conversion, type restricted version of .';Specialised numeric conversion, type restricted version of .(;Specialised numeric conversion, type restricted version of .);Specialised numeric conversion, type restricted version of .0      !"#$%&'()*+,-./012%&'()%&'()Safe+F&*A constraint which documents that a function is partial, and on GHC 8.0 and above produces a stack trace on failure. For example:  myHead :: *7 => [a] -> a myHead [] = error "bad" myHead (x:xs) = x  When using *B with GHC 7.8 or below you need to enable the language feature ConstraintKinds, e.g.  {-# LANGUAGE ConstraintKinds #-} at the top of the file.*Safe+N>+aApply some operation repeatedly, producing an element of output and the remainder of the list. \xs -> repeatedly (splitAt 3) xs == chunksOf 3 xs \xs -> repeatedly word1 (trim xs) == words xs \xs -> repeatedly line1 xs == lines xs,Flipped version of 3. for [1,2,3] (+1) == [2,3,4]-3Are two lists disjoint, with no elements in common. >disjoint [1,2,3] [4,5] == True disjoint [1,2,3] [4,1] == False.1Is there any element which occurs more than once. anySame [1,1,2] == True anySame [1,2,3] == False anySame (1:2:1:undefined) == True anySame [] == False \xs -> anySame xs == (length (nub xs) < length xs)/Are all elements the same. allSame [1,1,2] == False allSame [1,1,1] == True allSame [1] == True allSame [] == True allSame (1:1:2:undefined) == False \xs -> allSame xs == (length (nub xs) <= 1)0*Non-recursive transform over a list, like 4. list 1 (\v _ -> v - 2) [5,6,7] == 3 list 1 (\v _ -> v - 2) [] == 1 \nil cons xs -> maybe nil (uncurry cons) (uncons xs) == list nil cons xs1If the list is empty returns 5, otherwise returns the 6 and the 7. unsnoc "test" == Just ("tes",'t') unsnoc "" == Nothing \xs -> unsnoc xs == if null xs then Nothing else Just (init xs, last xs)2=Append an element to the start of a list, an alias for '(:)'. Ccons 't' "est" == "test" \x xs -> uncons (cons x xs) == Just (x,xs)3.Append an element to the end of a list, takes O(n) time. Csnoc "tes" 't' == "test" \xs x -> unsnoc (snoc xs x) == Just (xs,x)43Take a number of elements from the end of the list. takeEnd 3 "hello" == "llo" takeEnd 5 "bye" == "bye" takeEnd (-1) "bye" == "" \i xs -> takeEnd i xs `isSuffixOf` xs \i xs -> length (takeEnd i xs) == min (max 0 i) (length xs)53Drop a number of elements from the end of the list. dropEnd 3 "hello" == "he" dropEnd 5 "bye" == "" dropEnd (-1) "bye" == "bye" \i xs -> dropEnd i xs `isPrefixOf` xs \i xs -> length (dropEnd i xs) == max 0 (length xs - max 0 i) \i -> take 3 (dropEnd 5 [i..]) == take 3 [i..]66 n xs> returns a split where the second element tries to contain n elements. splitAtEnd 3 "hello" == ("he","llo") splitAtEnd 3 "he" == ("", "he") \i xs -> uncurry (++) (splitAt i xs) == xs \i xs -> splitAtEnd i xs == (dropEnd i xs, takeEnd i xs)78e against an enumeration. Never truncates the output - raises an error if the enumeration runs out. G\i xs -> zip [i..] xs == zipFrom i xs zipFrom False [1..3] == undefined87u generalised to any combining operation. Never truncates the output - raises an error if the enumeration runs out. -\i xs -> zipWithFrom (,) i xs == zipFrom i xs9 A merging of 9 and :. 4concatUnzip [("a","AB"),("bc","C")] == ("abc","ABC"): A merging of ; and :. DconcatUnzip3 [("a","AB",""),("bc","C","123")] == ("abc","ABC","123"); A version of < operating from the end. $takeWhileEnd even [2,3,4,6] == [4,6]<.Remove spaces from the start of a string, see >.=,Remove spaces from the end of a string, see >.>=Remove spaces from either side of a string. A combination of = and <. trim " hello " == "hello" trimStart " hello " == "hello " trimEnd " hello " == " hello" \s -> trim s == trimEnd (trimStart s)?Convert a string to lower case. 9lower "This is A TEST" == "this is a test" lower "" == ""@Convert a string to upper case. 9upper "This is A TEST" == "THIS IS A TEST" upper "" == ""ASplit the first word off a string. Useful for when starting to parse the beginning of a string, but you want to accurately preserve whitespace in the rest of the string. word1 "" == ("", "") word1 "keyword rest of string" == ("keyword","rest of string") word1 " keyword\n rest of string" == ("keyword","rest of string") \s -> fst (word1 s) == concat (take 1 $ words s) \s -> words (snd $ word1 s) == drop 1 (words s)B"Split the first line off a string. line1 "" == ("", "") line1 "test" == ("test","") line1 "test\n" == ("test","") line1 "test\nrest" == ("test","rest") line1 "test\nrest\nmore" == ("test","rest\nmore")CFEscape a string such that it can be inserted into an HTML document or "M attribute without any special interpretation. This requires escaping the <, >, & and "" characters. Note that it does not escape '$, so will not work when placed in a '7 delimited attribute. Also note that it will escape "G even though that is not required in an HTML body (but is not harmful). escapeHTML "this is a test" == "this is a test" escapeHTML "<b>\"g&t\"</n>" == "&lt;b&gt;&quot;g&amp;t&quot;&lt;/n&gt;" escapeHTML "don't" == "don't"D Invert of C& (does not do general HTML unescaping) )\xs -> unescapeHTML (escapeHTML xs) == xsEEscape a string so it can form part of a JSON literal. This requires escaping the special whitespace and control characters. Additionally, Note that it does not( add quote characters around the string. escapeJSON "this is a test" == "this is a test" escapeJSON "\ttab\nnewline\\" == "\\ttab\\nnewline\\\\" escapeJSON "\ESC[0mHello" == "\\u001b[0mHello"F&General JSON unescaping, inversion of E and all other JSON escapes. )\xs -> unescapeJSON (escapeJSON xs) == xsG A version of =4 where the equality is done on some extracted value.H A version of >8 where the equality is done on some extracted value. nubOn f is equivalent to  nubBy ((==) ? f):, but has the performance advantage of only evaluating f, once for each element in the input list.I A version of @6 where the comparison is done on some extracted value.J A version of A6 where the comparison is done on some extracted value.KA combination of = and B. groupSort [(1,'t'),(3,'t'),(2,'e'),(2,'s')] == [(1,"t"),(2,"es"),(3,"t")] \xs -> map fst (groupSort xs) == sort (nub (map fst xs)) \xs -> concatMap snd (groupSort xs) == map snd (sortOn fst xs)LA combination of = and B*, using a part of the value to compare on. UgroupSortOn length ["test","of","sized","item"] == [["of"],["test","item"],["sized"]]MA combination of = and B", using a predicate to compare on. dgroupSortBy (compare `on` length) ["test","of","sized","item"] == [["of"],["test","item"],["sized"]]N0Merge two lists which are assumed to be ordered. Rmerge "ace" "bd" == "abcde" \xs ys -> merge (sort xs) (sort ys) == sort (xs ++ ys)OLike N&, but with a custom ordering function.P]Replace a subsequence everywhere it occurs. The first argument must not be the empty list. replace "el" "_" "Hello Bella" == "H_lo B_la" replace "el" "e" "Hello" == "Helo" replace "" "e" "Hello" == undefined \xs ys -> not (null xs) ==> replace xs xs ys == ysQBreak, but from the end. breakEnd isLower "youRE" == ("you","RE") breakEnd isLower "youre" == ("youre","") breakEnd isLower "YOURE" == ("","YOURE") \f xs -> breakEnd (not . f) xs == spanEnd f xsRSpan, but from the end. spanEnd isUpper "youRE" == ("you","RE") spanEnd (not . isSpace) "x y z" == ("x y ","z") \f xs -> uncurry (++) (spanEnd f xs) == xs \f xs -> spanEnd f xs == swap (both reverse (span f (reverse xs)))S A variant of Cp with a custom test. In particular, adjacent separators are discarded, as are leading or trailing separators. ]wordsBy (== ':') "::xyz:abc::123::" == ["xyz","abc","123"] \s -> wordsBy isSpace s == words sT A variant of D] with a custom test. In particular, if there is a trailing separator it will be discarded. linesBy (== ':') "::xyz:abc::123::" == ["","","xyz","abc","","123",""] \s -> linesBy (== '\n') s == lines s linesBy (== ';') "my;list;here;" == ["my","list","here"]UAFind the first element of a list for which the operation returns E2, along with the result of the operation. Like F but useful where the function also computes some expensive information that can be reused. Particular useful when the function is monadic, see  firstJustM. RfirstJust id [Nothing,Just 3] == Just 3 firstJust id [Nothing,Nothing] == NothingVEquivalent to drop 1., but likely to be faster and a single lexeme. Mdrop1 "" == "" drop1 "test" == "est" \xs -> drop 1 xs == drop1 xsW Version on G generalised to a H rather than just a list. JmconcatMap Sum [1,2,3] == Sum 6 \f xs -> mconcatMap f xs == concatMap f xsXFind the first instance of needle in haystack=. The first element of the returned tuple is the prefix of haystack before needle. is matched. The second is the remainder of haystack6, starting with the match. If you want the remainder without the match, use `. breakOn "::" "a::b::c" == ("a", "::b::c") breakOn "/" "foobar" == ("foobar", "") \needle haystack -> let (prefix,match) = breakOn needle haystack in prefix ++ match == haystackY Similar to X+, but searches from the end of the string.9The first element of the returned tuple is the prefix of haystack( up to and including the last match of needle#. The second is the remainder of haystack, following the match. ,breakOnEnd "::" "a::b::c" == ("a::b::", "c")ZBreak a list into pieces separated by the first list argument, consuming the delimiter. An empty delimiter is invalid, and will cause an error to be raised. <splitOn "\r\n" "a\r\nb\r\nd\r\ne" == ["a","b","d","e"] splitOn "aaa" "aaaXaaaXaaaXaaa" == ["","X","X","X",""] splitOn "x" "x" == ["",""] splitOn "x" "" == [""] \s x -> s /= "" ==> intercalate s (splitOn s x) == x \c x -> splitOn [c] x == split (==c) x[Splits a list into components delimited by separators, where the predicate returns True for a separator element. The resulting components do not contain the separators. Two adjacent separators result in an empty component in the output. split (== 'a') "aabbaca" == ["","","bb","c",""] split (== 'a') "" == [""] split (== ':') "::xyz:abc::123::" == ["","","xyz","abc","","123","",""] split (== ',') "my,list,here" == ["my","list","here"]\ A version of  ; but with different strictness properties. The function  [ can be used on an infinite list and tests the property on each character. In contrast, \o is strict in the spine of the list but only tests the trailing suffix. This version usually outperforms  t if the list is short or the test is expensive. Note the tests below cover both the prime and non-prime variants. dropWhileEnd isSpace "ab cde " == "ab cde" dropWhileEnd' isSpace "ab cde " == "ab cde" last (dropWhileEnd even [undefined,3]) == undefined last (dropWhileEnd' even [undefined,3]) == 3 head (dropWhileEnd even (3:undefined)) == 3 head (dropWhileEnd' even (3:undefined)) == undefined]|Drops the given prefix from a list. It returns the original sequence if the sequence doesn't start with the given prefix. MdropPrefix "Mr. " "Mr. Men" == "Men" dropPrefix "Mr. " "Dr. Men" == "Dr. Men"^zDrops the given suffix from a list. It returns the original sequence if the sequence doesn't end with the given suffix. dropSuffix "!" "Hello World!" == "Hello World" dropSuffix "!" "Hello World!!" == "Hello World!" dropSuffix "!" "Hello World." == "Hello World."_TReturn the prefix of the second list if its suffix matches the entire first list. Examples: wstripSuffix "bar" "foobar" == Just "foo" stripSuffix "" "baz" == Just "baz" stripSuffix "foo" "quux" == Nothing`@Return the the string before and after the search string, or 5% if the search string is not present. Examples: TstripInfix "::" "a::b::c" == Just ("a", "b::c") stripInfix "/" "foobar" == Nothinga Similar to `+, but searches from the end of the string. 2stripInfixEnd "::" "a::b::c" == Just ("a::b", "c")bSplit a list into chunks of a given size. The last chunk may contain fewer than n elements. The chunk size must be positive. chunksOf 3 "my test" == ["my ","tes","t"] chunksOf 3 "mytest" == ["myt","est"] chunksOf 8 "" == [] chunksOf 0 "test" == undefinedc O(n log n). The c function sorts and removes duplicate elements from a list. In particular, it keeps only the first occurrence of each element. HnubSort "this is a test" == " aehist" \xs -> nubSort xs == nub (sort xs)d A version of c* which operates on a portion of the value. >nubSortOn length ["a","test","of","this"] == ["a","of","test"]e A version of c with a custom predicate. MnubSortBy (compare `on` length) ["a","test","of","this"] == ["a","of","test"]f O(n log n). The f function removes duplicate elements from a list. In particular, it keeps only the first occurrence of each element. Unlike the standard >$ operator, this version requires an I7 instance and consequently runs asymptotically faster. onubOrd "this is a test" == "this ae" nubOrd (take 4 ("this" ++ undefined)) == "this" \xs -> nubOrd xs == nub xsg A version of f* which operates on a portion of the value. =nubOrdOn length ["a","test","of","this"] == ["a","test","of"]h A version of f with a custom predicate. LnubOrdBy (compare `on` length) ["a","test","of","this"] == ["a","test","of"]JK83LMNOPQRST@AUVWXFYZ[\]^_G:`CaDb cBdefgh=ijklmnopqrstuvwxyz{|}~> ;9<67+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghA?@><=ABCEDF546QR \;_`a]^STXYZ[b0123VWKLMfhgHG cedIJ-/.+,U9:78PNOSafe+kRead a  or throw an exception. G\x -> readVersion (showVersion x) == x readVersion "hello" == undefinedkk Safe+ClThe l( function extracts the element out of a + and throws an error if its argument is . Much like fromJust=, using this function in polished code is usually a bad idea. E\x -> fromLeft' (Left x) == x \x -> fromLeft' (Right x) == undefinedmThe m( function extracts the element out of a + and throws an error if its argument is . Much like fromJust=, using this function in polished code is usually a bad idea. G\x -> fromRight' (Right x) == x \x -> fromRight' (Left x) == undefinednPull the value out of an / where both alternatives have the same type. ?\x -> fromEither (Left x ) == x \x -> fromEither (Right x) == xoGiven a , convert it to an (, providing a suitable value for the  should the value be 5. S\a b -> maybeToEither a (Just b) == Right b \a -> maybeToEither a Nothing == Left ap Given an , convert it to a , where  becomes 5. O\x -> eitherToMaybe (Left x) == Nothing \x -> eitherToMaybe (Right x) == Just xlmnop nlmpoSafe+Voq[Fully evaluate an input String. If the String contains embedded exceptions it will produce  <Exception>. (stringException "test" == return "test" stringException ("test" ++ undefined) == return "test<Exception>" stringException ("test" ++ undefined ++ "hello") == return "test<Exception>" stringException ['t','e','s','t',undefined] == return "test<Exception>"r@Show a value, but if the result contains exceptions, produce  <Exception> . Defined as q . show. Particularly useful for printing exceptions to users, remembering that exceptions can themselves contain undefined values.s+Ignore any exceptions thrown by the action. ?ignore (print 1) == print 1 ignore (fail "die") == return ()tLike error, but in the  monad. Note that while  in  raises an , this function raises an  exception. :try (errorIO "Hello") == return (Left (ErrorCall "Hello"))uRetry an operation at most n times (n2 must be positive). If the operation fails the n+th time it will throw that final exception. Dretry 1 (print "x") == print "x" retry 3 (fail "die") == fail "die"vRetry an operation at most n times (nh must be positive), while the exception value and type match a predicate. If the operation fails the n+th time it will throw that final exception.w A version of  without the  context, restricted to , so catches all exceptions.xLike w but for yLike w but for zLike w but for {Like w but for |Like w but for }pCatch an exception if the predicate passes, then call the handler with the original exception. As an example: ZreadFileExists x == catchBool isDoesNotExistError (readFile "myfile") (const $ return "") ~Like } but for .Like } but for .j     *qrstuvwxyz{|}~*uvrqt swy{xz|}~ Safe+TPerform some operation on E, given the field inside the E. GwhenJust Nothing print == return () whenJust (Just 1) print == print 1Like $, but where the test can be monadic.>The identity function which requires the inner argument to be ()7. Useful for functions with overloaded return types. \(x :: Maybe ()) -> unit x == xMonadic generalisation of 4.Monadic generalisation of . A variant of H that has no base case, and thus may only be applied to non-empty lists. Yfold1M (\x y -> Just x) [] == undefined fold1M (\x y -> Just $ x + y) [1, 2, 3] == Just 6Like  but discards the result. A version of  partition% that works with a monadic predicate. cpartitionM (Just . even) [1,2,3] == Just ([2], [1,3]) partitionM (const Nothing) [1,2,3] == Nothing A version of G% that works with a monadic predicate.Like I, but has its arguments flipped, so can be used instead of the common fmap concat $ forM pattern. A version of  mconcatMap% that works with a monadic predicate. A version of % that works with a monadic predicate.1A looping operation, where the predicate returns # as a seed for the next loop or  to abort the loop.+Keep running an operation until it becomes . As an example: IwhileM $ do sleep 0.1; notM $ doesFileExist "foo.txt" readFile "foo.txt" 8If you need some state persisted between each test, use .Like $, but where the test can be monadic.Like $, but where the test can be monadic.Like if$, but where the test can be monadic.Like $, but where the test can be monadic. The lazy C operator lifted to a monad. If the first argument evaluates to . the second argument will not be evaluated. uJust True ||^ undefined == Just True Just False ||^ Just True == Just True Just False ||^ Just False == Just False The lazy  C operator lifted to a monad. If the first argument evaluates to . the second argument will not be evaluated. vJust False &&^ undefined == Just False Just True &&^ Just True == Just True Just True &&^ Just False == Just False A version of ]; lifted to a monad. Retains the short-circuiting behaviour. anyM Just [False,True ,undefined] == Just True anyM Just [False,False,undefined] == undefined \(f :: Int -> Maybe Bool) xs -> anyM f xs == orM (map f xs) A version of \; lifted to a monad. Retains the short-circuiting behaviour. allM Just [True,False,undefined] == Just False allM Just [True,True ,undefined] == undefined \(f :: Int -> Maybe Bool) xs -> anyM f xs == orM (map f xs) A version of ^; lifted to a monad. Retains the short-circuiting behaviour. orM [Just False,Just True ,undefined] == Just True orM [Just False,Just False,undefined] == undefined \xs -> Just (or xs) == orM (map Just xs) A version of _; lifted to a monad. Retains the short-circuiting behaviour. andM [Just True,Just False,undefined] == Just False andM [Just True,Just True ,undefined] == undefined \xs -> Just (and xs) == andM (map Just xs)Like find$, but where the test can be monadic. findM (Just . isUpper) "teST" == Just (Just 'S') findM (Just . isUpper) "test" == Just Nothing findM (Just . const True) ["x",undefined] == Just (Just "x")Like N, but also allows you to compute some additional information in the predicate.D!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFSafe+N=Starts out empty, then is filled exactly once. As an example: bar <-  forkIO $ do ...; val <- ...;  bar val print =<<  bar PHere we create a barrier which will contain some computed value. A thread is forked to fill the barrier, while the main thread waits for it to complete. A barrier has similarities to a future or promise from other languages, has been known as an IVar in other Haskell work, and in some ways is like a manually managed thunk.Like an Gk, but must always be full. Used to operate on a mutable variable in a thread-safe way. As an example: hits <-  0 forkIO $ do ...;  hits (+1); ... i <-  hits print ("HITS",i) iHere we have a variable which we modify atomically, so modifications are not interleaved. This use of G never blocks on a put. No modifyVar operation should ever block, and they should always complete in a reasonable timeframe. A q should not be used to protect some external resource, only the variable contained within. Information from a 6 should not be subsequently inserted back into the .Like an Gu, but has no value. Used to guarantee single-threaded access, typically to some system resource. As an example: lock <-  let output = L . putStrLn forkIO $ do ...; output "hello" forkIO $ do ...; output "world" sHere we are creating a lock to ensure that when writing output our messages do not get interleaved. This use of G never blocks on a put. It is permissible, but rare, that a withLock contains a withLock inside it - but if so, watch out for deadlocks.On GHC 7.6 and above with the  -threaded flag, brackets a call to #. On lower versions (which lack .) this function just runs the argument action.Given an action, produce a wrapped action that runs at most once. If the function raises an exception, the same exception will be reraised each time. let x ||| y = do t1 <- onceFork x; t2 <- onceFork y; t1; t2 \(x :: IO Int) -> void (once x) == return () \(x :: IO Int) -> join (once x) == x \(x :: IO Int) -> (do y <- once x; y; y) == x \(x :: IO Int) -> (do y <- once x; y ||| y) == xLike H, but immediately starts running the computation on a background thread. Z\(x :: IO Int) -> join (onceFork x) == x \(x :: IO Int) -> (do a <- onceFork x; a; a) == x Create a new .%Perform some operation while holding 6. Will prevent all other operations from using the  while the action is ongoing.Like Y but will never block. If the operation cannot be executed immediately it will return 5. Create a new  with a value.Read the current value of the .)Write a value to become the new value of . Modify a + producing a new value and a return result. Modify a , a restricted version of ..Perform some operation using the value in the , a restricted version of . Create a new .4Write a value into the Barrier, releasing anyone at +. Any subsequent attempts to signal the  will throw an exception.,Wait until a barrier has been signaled with . A version of  that never blocks, returning 5- if the barrier has not yet been signaled.PHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~GSafeList the files and directories directly within a directory. Each result will be prefixed by the query directory, and the special directories . and ..9 will be ignored. Intended as a cleaned up version of . withTempDir $ \dir -> do writeFile (dir </> "test.txt") ""; (== [dir </> "test.txt"]) <$> listContents dir let touch = mapM_ $ \x -> createDirectoryIfMissing True (takeDirectory x) >> writeFile x "" let listTest op as bs = withTempDir $ \dir -> do touch $ map (dir </>) as; res <- op dir; return $ map (drop (length dir + 1)) res == bs listTest listContents ["bar.txt","foo/baz.txt","zoo"] ["bar.txt","foo","zoo"]Like y, but only returns the files in a directory, not other directories. Each file will be prefixed by the query directory. DlistTest listFiles ["bar.txt","foo/baz.txt","zoo"] ["bar.txt","zoo"]Like , but goes recursively through all subdirectories. This function will follow symlinks, and if they form a loop, this function will not terminate. glistTest listFilesRecursive ["bar.txt","zoo","foo" </> "baz.txt"] ["bar.txt","zoo","foo" </> "baz.txt"]Like _, but with a predicate to decide where to recurse into. Typically directories starting with .V would be ignored. The initial argument directory will have the test applied to it. listTest (listFilesInside $ return . not . isPrefixOf "." . takeFileName) ["bar.txt","foo" </> "baz.txt",".foo" </> "baz2.txt", "zoo"] ["bar.txt","zoo","foo" </> "baz.txt"] listTest (listFilesInside $ const $ return False) ["bar.txt"] []|Create a directory with permissions so that only the current user can view it. On Windows this function is equivalent to .@SafeY NoneVLike , but setting an encoding.Like , but with the encoding .Like , but for binary files.A strict version of .A strict version of . When the string is produced, the entire file will have been read into memory and the file handle will have been closed. Closing the file handle does not rely on the garbage collector. f\(filter isHexDigit -> s) -> fmap (== s) $ withTempFile $ \file -> do writeFile file s; readFile' fileA strict version of , see  for details.A strict version of , see  for details.A strict version of , see  for details.(Write a file with a particular encoding.Write a file with the  encoding. W\s -> withTempFile $ \file -> do writeFileUTF8 file s; fmap (== s) $ readFileUTF8' fileWrite a binary file. i\(ASCIIString s) -> withTempFile $ \file -> do writeFileBinary file s; fmap (== s) $ readFileBinary' file Capture the  and  of a computation. ,captureOutput (print 1) == return ("1\n",()) Execute an action with a custom , a wrapper around .nProvide a function to create a temporary file, and a way to delete a temporary file. Most users should use $ which combines these operations.Like ( but using a custom temporary directory.Create a temporary file in the temporary directory. The file will be deleted after the action completes (provided the file is not still open). The  will not have any file extension, will exist, and will be zero bytes long. If you require a file with a specific name, use . withTempFile doesFileExist == return True (doesFileExist =<< withTempFile return) == return False withTempFile readFile' == return ""xProvide a function to create a temporary directory, and a way to delete a temporary directory. Most users should use $ which combines these operations.Like ( but using a custom temporary directory.Create a temporary directory inside the system temporary directory. The directory will be deleted after the action completes. withTempDir doesDirectoryExist == return True (doesDirectoryExist =<< withTempDir return) == return False withTempDir listFiles == return []Returns $ when both files have the same size.Returns - when the contents of both files is the same.Returns S if both files have the same content. Raises an error if either file is missing. fileEq "does_not_exist1" "does_not_exist2" == undefined fileEq "does_not_exist" "does_not_exist" == undefined withTempFile $ \f1 -> fileEq "does_not_exist" f1 == undefined withTempFile $ \f1 -> withTempFile $ \f2 -> fileEq f1 f2 withTempFile $ \f1 -> withTempFile $ \f2 -> writeFile f1 "a" >> writeFile f2 "a" >> fileEq f1 f2 withTempFile $ \f1 -> withTempFile $ \f2 -> writeFile f1 "a" >> writeFile f2 "b" >> notM (fileEq f1 f2)}      !"#$%&'()*+,-./01234SafemReturn  on Windows and ! otherwise. A runtime version of #ifdef minw32_HOST_OS. Equivalent to os == "mingw32", but: more efficient; doesn't require typing an easily mistypeable string; actually asks about your OS not a library; doesn't bake in 32bit assumptions that are already false. </rant> isWindows == (os == "mingw32")Return  on Mac OS X and  otherwise.5678None+N A version of 9% that also captures the output, both  and . Returns a pair of the : and the output. A version of 9 that throws an error if the : is not ;. A version of 9 that captures the output (both  and  ) and throws an error if the : is not ;.7<9=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnSafe1.A type alias for seconds, which are stored as o.Sleep for a number of seconds. 3fmap (round . fst) (duration $ sleep 1) == return 1 A version of  that takes ) and never overflows the bounds of an pM. In addition, the bug that negative timeouts run for ever has been fixed. timeout (-3) (print 1) == return Nothing timeout 0.1 (print 1) == fmap Just (print 1) do (t, _) <- duration $ timeout 0.1 $ sleep 1000; print t; return $ t < 1 timeout 0.1 (sleep 2 >> print 1) == return NothingnShow a number of seconds, typically a duration, in a suitable manner with reasonable precision for a human. showDuration 3.435 == "3.44s" showDuration 623.8 == "10m24s" showDuration 62003.8 == "17h13m" showDuration 1e8 == "27777h47m"Call once to start, then call repeatedly to get the elapsed time since the first call. The time is guaranteed to be monotonic. This function is robust to system time changes. Ado f <- offsetTime; xs <- replicateM 10 f; return $ xs == sort xsA synonym for .'Record how long a computation takes in . ;do (a,_) <- duration $ sleep 1; return $ a >= 1 && a <= 1.1qrSafe1)stuvwx yz{|}~ None  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghklmnopqrstuvwxyz{|}~*uvrqt swy{xz|}~nlmpo?@><=ABCEDF546QR \;_`a]^STXYZ[b0123VWKLMfhgHG cedIJ-/.+,U9:78PNO !"#$ k%&'()  !"#"$%&%'%()*+,-.-/0102343536378989:;:<=>?@ABCDE F G   H I J K L M N O P QRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~  %%%    + +++++++++++++++++++ +!+"+#+$+%+&+'+(+)*+,-.:/:0121345464748494:4;4<4=4>4?4@4A4B4C4D4E4F4G4H4I4J4KLMLNLOLPLQLRLSLTLULVLWLXLYLZL[\]4^4_4`1abcdebf=g=h=i=jkl=m=n-o-pqrkskt-u-v-wbxkykzb{ |}b~=kkkkkkkkkkkkkkkkk--------------------------------------------------========================      333b3333  b)))b      " !"#$%&'()*+,-./0123)4)5)6))7)8)9):);)<)=)>)?@dA  BbC?D |E |F  G |H?IbJbKbLbMbNbObPQR?S?T?U?V?W?X?Y?Z?[?\?]?^_k`kakbkcdebfbgbhbibjbkblbmbnbopqrstuvwxyz{|}|~|||||||""""""""""pppppppppABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABA      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZZ[\]^]_]`]abcdedfdgdhdijkjljmjnopqrsoptopuopvopwopxopyopzop{op|op}op~opopopopopopopopopopoooooooooooooooooooooooooooooo    \\\\\00\\\\\\"extra-1.6.7-3EefTiS3LKGLR5ZAOL7ID2Control.Concurrent.ExtraSystem.Environment.ExtraData.Version.ExtraData.IORef.ExtraControl.Exception.ExtraData.Typeable.ExtraData.List.ExtraText.Read.ExtraData.Either.ExtraExtraData.Tuple.Extra Numeric.ExtraControl.Monad.ExtraSystem.Directory.ExtraSystem.IO.ExtraSystem.Info.ExtraSystem.Process.ExtraSystem.Time.Extra Control.Arrow***&&&PartialSystem.TimeouttimeoutbaseControl.Concurrent forkFinallySystem.Environment lookupEnv!System.Environment.ExecutablePathgetExecutablePath Data.Version makeVersion GHC.Conc.SyncsetNumCapabilitiesgetNumCapabilities Data.IORefatomicWriteIORefatomicModifyIORef' modifyIORef' GHC.ExceptiondisplayException Data.TypeabletypeRep Data.OldListsortOn dropWhileEnd Text.Read readMaybe readEither Data.Either fromRightfromLeftisRightisLeft Data.ProxyProxyData.Type.EqualityRefl:~:GHC.ListunconsGHC.ErrerrorWithoutStackTracedirectory-1.3.0.2System.DirectorywithCurrentDirectory writeIORef'atomicWriteIORef'firstseconddupebothfst3snd3thd3showDP intToDouble intToFloat floatToDouble doubleToFloat repeatedlyfordisjointanySameallSamelistunsnocconssnoctakeEnddropEnd splitAtEndzipFrom zipWithFrom concatUnzip concatUnzip3 takeWhileEnd trimStarttrimEndtrimlowerupperword1line1 escapeHTML unescapeHTML escapeJSON unescapeJSONgroupOnnubOn maximumOn minimumOn groupSort groupSortOn groupSortBymergemergeByreplacebreakEndspanEndwordsBylinesBy firstJustdrop1 mconcatMapbreakOn breakOnEndsplitOnsplit dropWhileEnd' dropPrefix dropSuffix stripSuffix stripInfix stripInfixEndchunksOfnubSort nubSortOn nubSortBynubOrdnubOrdOnnubOrdBy $fShowColor$fShowRB readVersion fromLeft' fromRight' fromEither maybeToEither eitherToMaybestringException showExceptionignoreerrorIOretry retryBoolcatch_ catchJust_handle_ handleJust_try_tryJust_ catchBool handleBooltryBoolwhenJust whenJustMunitmaybeMeitherMfold1Mfold1M_ partitionM concatMapM concatForM mconcatMapM mapMaybeMloopMwhileMwhenMunlessMifMnotM||^&&^anyMallMorMandMfindM firstJustMBarrierVarLockwithNumCapabilitiesonceonceForknewLockwithLock withLockTrynewVarreadVarwriteVar modifyVar modifyVar_withVar newBarrier signalBarrier waitBarrierwaitBarrierMaybe listContents listFileslistFilesRecursivelistFilesInsidecreateDirectoryPrivatereadFileEncoding readFileUTF8readFileBinary readFile'readFileEncoding' readFileUTF8'readFileBinary'writeFileEncoding writeFileUTF8writeFileBinary captureOutput withBuffering newTempFilenewTempFileWithin withTempFile newTempDirnewTempDirWithin withTempDirfileEq isWindowsisMac systemOutputsystem_ systemOutput_Secondssleep showDuration offsetTimeoffsetTimeIncreaseduration$fExceptionTimeout $fShowTimeout $fEqTimeout GHC.IORef writeIORefatomicModifyIORef modifyIORef mkWeakIORef readIORefnewIORefIORef Data.TuplefstsndswapuncurrycurryData.Typeable.InternalTypeableghc-prim GHC.TypesTyContypeOf7typeOf6typeOf5typeOf4typeOf3typeOf2typeOf1 rnfTypeReptypeRepFingerprint typeRepTyCon typeRepArgs splitTyConAppmkFunTy funResultTygcast2gcast1gcasteqTcast showsTypeReptypeOfTypeRep Typeable1 Typeable2 Typeable3 Typeable4 Typeable5 Typeable6 Typeable7rnfTyContyConFingerprint tyConName tyConModule tyConPackage:~~:HReflGHC.Real fromIntegral realToFrac GHC.FloatFloatingpiexplogsqrt**logBasesincostanasinacosatansinhcoshtanhasinhacoshatanhlog1pexpm1log1pexplog1mexpNumericshowOctshowHex showIntAtBase showGFloatAlt showFFloatAlt showGFloat showFFloat showEFloatshowInt readSigned readFloatreadHexreadDecreadOctreadIntGHC.Read lexDigitsfromRat floatToDigits showFloat showSignedGHC.Basemap Data.MaybemaybeNothinginitlastzipunzip Data.Foldableconcatunzip3 takeWhilegroupnub Data.FunctiononmaximumminimumsortwordslinesJustfind concatMapMonoid GHC.ClassesOrd++filterfoldrnulllengthfoldlfoldl'foldl1sumproductfoldr1elem Data.ListisSubsequenceOfData.Traversable mapAccumR mapAccumLnotElem minimumBy maximumByallanyorandunwordsunlinesunfoldrsortBy permutations subsequencestailsinitsgroupBydeleteFirstsByunzip7unzip6unzip5unzip4zipWith7zipWith6zipWith5zipWith4zip7zip6zip5zip4genericReplicate genericIndexgenericSplitAt genericDrop genericTake genericLengthinsertByinsert partition transpose intercalate intersperse intersectBy intersectunionByunion\\deleteBydeletenubBy isInfixOf isSuffixOf isPrefixOf findIndices findIndex elemIndices elemIndex stripPrefixzipWith3zipWithzip3!!lookupreversebreakspansplitAtdroptake dropWhilecycle replicaterepeatiteratescanr1scanrscanl'scanl1scanlfoldl1'tailheadRBETColorRBVersion parseVersion showVersion versionBranch versionTagsLeftRightEitherMaybepartitionEithersrightsleftseitherIOfailGHC.IO.Exception IOException ErrorCallGHC.IOcatch Exception SomeExceptionControl.Exception.Base catchJusthandle handleJusttrytryJustassertControl.ExceptionallowInterruptcatchesHandlerbracketOnErrorbracket_finallybracket onException mapExceptionPatternMatchFail RecSelError RecConError RecUpdError NoMethodError TypeErrorNonTerminationNestedAtomicallythrowToioErrorasyncExceptionFromExceptionasyncExceptionToExceptionBlockedIndefinitelyOnMVarBlockedIndefinitelyOnSTMDeadlockAllocationLimitExceededCompactionFailedAssertionFailedSomeAsyncExceptionAsyncException StackOverflow HeapOverflow ThreadKilled UserInterruptArrayExceptionIndexOutOfBoundsUndefinedElementevaluateuninterruptibleMaskuninterruptibleMask_maskmask_getMaskingState interruptiblethrowIO MaskingStateUnmaskedMaskedInterruptibleMaskedUninterruptiblethrow toException fromExceptionErrorCallWithLocationArithExceptionOverflow UnderflowLossOfPrecision DivideByZeroDenormalRatioZeroDenominator Control.MonadfoldMmapMaybeFalsewhenunlessnot||True&&guardjoinMonad>>=>>returnFunctorfmapmapMsequencemfilter<$!> replicateM_ replicateMfoldM_ zipWithM_zipWithM mapAndUnzipMforever<=<>=>filterMforMmsum sequence_forM_mapM_ Data.FunctorvoidapliftM5liftM4liftM3liftM2liftM=<< MonadPlusmzeromplusGHC.MVarMVarthreadWaitWriteSTMthreadWaitReadSTMthreadWaitWritethreadWaitReadrunInUnboundThreadrunInBoundThreadisCurrentThreadBoundforkOSWithUnmaskforkOSrtsSupportsBoundThreadsControl.Concurrent.ChanwriteList2ChangetChanContents isEmptyChan unGetChandupChanreadChan writeChannewChanChanControl.Concurrent.QSem signalQSemwaitQSemnewQSemQSemControl.Concurrent.QSemN signalQSemN waitQSemNnewQSemNQSemN GHC.Conc.IO threadDelayControl.Concurrent.MVar mkWeakMVaraddMVarFinalizermodifyMVarMaskedmodifyMVarMasked_ modifyMVar modifyMVar_withMVarMaskedwithMVarswapMVarmkWeakThreadIdthreadCapabilityyield myThreadId killThreadforkOnWithUnmaskforkOnforkIOWithUnmaskforkIOThreadId isEmptyMVar tryReadMVar tryPutMVar tryTakeMVarputMVarreadMVartakeMVarnewMVar newEmptyMVarOnce OncePending OnceRunningOnceDonegetDirectoryContentscreateDirectorygetTemporaryDirectorygetUserDocumentsDirectorygetAppUserDataDirectorygetXdgDirectorygetHomeDirectorysetModificationTime setAccessTimegetModificationTime getAccessTimeisSymbolicLinkpathIsSymbolicLink doesFileExistdoesDirectoryExist doesPathExist getFileSizesetCurrentDirectorygetCurrentDirectory listDirectory findFilesWith findFileWith findFilesfindFilefindExecutablesInDirectoriesfindExecutablesfindExecutablemakeRelativeToCurrentDirectory makeAbsolutecanonicalizePathcopyFileWithMetadatacopyFile renamePath renameFilerenameDirectory removeFileremovePathForciblyremoveDirectoryRecursiveremoveDirectorycreateDirectoryIfMissingcopyPermissionssetPermissionsgetPermissionssetOwnerSearchablesetOwnerExecutablesetOwnerWritablesetOwnerReadableemptyPermissions Permissionsreadablewritable executable searchable XdgDirectoryXdgData XdgConfigXdgCache System.Directory.Internal.Config exeExtensiongetEnvironment withProgNamewithArgsunsetEnvsetEnvgetEnv getProgNamegetArgs System.IOreadFileGHC.IO.Encodingutf8 hGetContents'GHC.IO.Handle.Text hGetContentsGHC.IO.Handle.FDstdoutstderrGHC.IO.Handle.Types BufferMode GHC.IO.Handle hSetBufferingFilePathsameSize sameContentprintHandle(openBinaryTempFileWithDefaultPermissions"openTempFileWithDefaultPermissionsopenBinaryTempFile openTempFilefixIOwithBinaryFilewithFilehPrinthReadylocaleEncodingreadIOreadLn appendFile writeFileinteract getContentsgetLinegetCharputStrLnputStrputCharhShowhSetNewlineModehSetBinaryModehIsTerminalDevicehGetEchohSetEcho hIsSeekable hGetBuffering hIsWritable hIsReadable hIsClosedhIsOpenhTellhSeekhSetPosnhGetPosn hGetEncoding hSetEncoding hLookAheadisEOFhIsEOF hSetFileSize hFileSizehClose HandlePosnopenBinaryFileopenFilestdinhGetBufNonBlocking hGetBufSomehGetBufhPutBufNonBlockinghPutBuf hPutStrLnhPutStrhPutCharhGetLinehGetChar hWaitForInputmkTextEncodingchar8utf32beutf32leutf32utf16beutf16leutf16utf8_bomlatin1hFlushnoNewlineTranslationnativeNewlineModeuniversalNewlineMode nativeNewline NoBuffering LineBufferingBlockBufferingNewlineLFCRLF NewlineModeinputNLoutputNL GHC.IO.DeviceSeekMode AbsoluteSeek RelativeSeek SeekFromEndGHC.IO.Encoding.Types TextEncoding GHC.IO.IOModeIOModeReadMode WriteMode AppendMode ReadWriteMode System.Info compilerNamearchoscompilerVersionprocess-1.6.1.0System.ProcesssystemExitCode ExitSuccess rawSystemrunInteractiveProcessrunInteractiveCommand runProcess runCommandterminateProcessgetProcessExitCodewaitForProcessshowCommandForUserreadCreateProcessWithExitCodereadProcessWithExitCodereadCreateProcess readProcess callCommand callProcess spawnCommand spawnProcesswithCreateProcess createProcessshellprocSystem.Process.InternalsinterruptProcessGroupOf createPipeFd createPipecreateProcess_System.Process.Common CreateProcesscmdspeccwdenvstd_instd_outstd_err close_fds create_group delegate_ctlcdetach_consolecreate_new_console new_session child_group child_useruse_process_jobsCmdSpec ShellCommand RawCommand StdStreamInherit UseHandle CreatePipeNoStream ProcessHandleDoubleIntTimeoutRead readsPrecreadListreadPrec readListPrecreadreadsparenslexPlexreadListPrecDefaultreadListDefault readParen Text.Read.LexLexemeCharSymbolStringNumberPuncIdentEOFText.ParserCombinators.ReadPrec readS_to_Prec readPrec_to_S readP_to_Prec readPrec_to_Pchoicepfail<+++++lookgetprecresetstepliftminPrecReadPrecPrecText.ParserCombinators.ReadPReadS