HOOG2[oqf./<>a $)1b ,,c  %++--d  !!%&-.22e )+1f ##))11g h  $$*+i !#%+-2jk,1l   #%+11m ##)),,11n   "#'),,/2o  !"$%'(--/022p +q r   &++-.s   ""$,/022t  !"$1u v&&..w22x  ""'(/0y!!--cbab()->AllbAnyA BlockReason4Bool"CCharCClockCDevvCDoubleCFloatCIno|CInt4CIntMaxCIntPtrCLDoubleKCLLongCLongCModesCOff+CPidCPtrdiffCSCharSCShort  CSigAtomicCSize{CSsize3CTimeCUCharCUIntqCUIntMax)CUIntPtrCULLongCULongQCUShort CWcharChanCharComplex ConsoleEventhConstr_ ConstrRepVDataRepMDataTypeGDouble.DynamicE12E6EitherErrno ExceptionFdFixity{FloatbGeneralCategory@HashData7IO!Id InsertsInt Int16 Int32 Int64 Int8 IntPtr; Integer# Lexeme Maybe NestedAtomically NoMethodError NonTermination Orderingp P_ PatternMatchFailF QSem< QSemN2 ReadP ReadPrec RecConError RecSelError RecUpdError STM StableName TVar ThreadIdp ThreadStatusc TimeoutG Unique? Version$ Word Word16 Word32 Word64 Word8 WordPtr_ ZipListJ [::]; []  TraversableFoldable Applicative AlternativeMonadFix MonadPlusFunctorMonadFunctor Applicative ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq PrintfArgDataStorable PrintfArgDataStorable PrintfArgDataStorable PrintfArgDataStorable PrintfArgDataStorableEqOrdShowReadTypeableOrdEqTypeableShow ExceptionEqShowOrdEqShowEqOrdTypeable Typeable1 Typeable1 Typeable1FunctorMonadTypeableShow ExceptionTypeableShow ExceptionTypeableShow ExceptionFunctorMonad MonadPlusFunctorMonad MonadPlusTypeableTypeableTypeableShow ExceptionMonad MonadPlusMonoidDataIxTypeableShow ExceptionTypeableShow ExceptionTypeableShow Exception TraversableFoldable Applicative AlternativeMonadFix MonadPlusFunctorMonadShowEq PrintfArgDataBitsIx ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq PrintfArgDataStorable PrintfArgDataStorable PrintfArgDataStorable PrintfArgDataStorable PrintfArgDataStorableBitsIxEqFunctor Applicative ApplicativeMonadFixShowEqIxBoundedShowReadEnumOrdEq PrintfArgDataStorableShowEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEqTypeable ExceptionShowEqEq Typeable2 HasResolution HasResolution ExceptionTypeableShow PrintfArgDataStorableShowShowEqShowEqShowEqReadShowEnumOrdEqTypeable Typeable1 PrintfArgIsCharDataStorableIx Typeable1 ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeable RealFloatRealFracFloating FractionalRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEq ReadShowTypeable RealFloatRealFracFloating FractionalRealStorableEnumNumOrdEq ReadShowTypeable RealFloatRealFracFloating FractionalRealStorableEnumNumOrdEq ReadShowTypeableRealStorableEnumNumOrdEq ReadShowTypeableRealStorableEnumNumOrdEq ReadShowTypeableBitsIntegralBoundedRealStorableEnumNumOrdEqDataStorableIxShowOrdEqMonoidBoundedShowReadOrdEqMonoidBoundedShowReadOrdEqArrow ArrowChoice ArrowApply ArrowLoopCategoryMonoidDataEqOrdIx ByteCount CString CStringLenCWString CWStringLen ClockTickConIndexDeviceID EpochTimeFileIDFileMode FileOffsetFilePathvFinalizerEnvPtrC FinalizerPtr IOErrorIPrLimitMicroPicoPrecProcessGroupID ProcessIDRationalReadS SampleVareShowSJString=[]Char[]Char[]CharaMVar(,)IntMVaraa[]Char[](,)a[]CharRatioIntegerCPidCPidIntFixedE12FixedE6CLong(,)IntInt IOExceptionaFunPtrPtraIO()envaFunPtrPtrenvPtraIO()[]CharCOffCModeCInoCTimeCDevIntCClock(,)PtrCWcharIntPtrCWchar(,)PtrCCharIntPtrCCharCSize(a[aa\bWcNdJe{GfsCgBh,Ai<j<k<l9m7n<4o1p).q-r)s$t u;vwziplistZipList#eora,item ode IOModep3ampDeKdRam^oenlasdz WrappedMonadrrow WrappedArrowonad WrappedMonadrrow  WrappedArrowr%d,Word#1368wpXt_rfWordPtrWord84Word642Word326Word16Word#akWeakWordersio#n*Versionn psLeSrZianhtoevr}ruptAsyncExceptionpercaselette r GeneralCategorydN i) q0 u7 e> UniqueeU f ra fh lo ov w} ArithExceptioni n e d e l e m e n t ArrayExceptionh+#i"rg"v7"y !c"p!e !aK!r,!e3!p:!TypeRepbR!lY!e`!Typeable1"2!3!4!5!6!7! Typeable7 Typeable6 Typeable5 Typeable4 Typeable3 Typeable2 Typeable1o!"n("TyCona>"rE"TVar#X"TVar#an"vu"e|"r"s"a"b"l"e" Traversablet"l"e"c"a"s"e"l"e"t#t#e#r#GeneralCategoryr2#e9#a@#dG#b$d$fI$i$k#r#sl#ts#az#t#u#s# ThreadStatusu#n#n#i#n#g# ThreadStatusi#l#l#e#d$AsyncExceptiond$ThreadId#6$ ThreadId#iP$nW$i^$se$hl$es$dz$ ThreadStatusi$e$d$ ThreadStatusl$o$c$k$e$d$ ThreadStatusa)e2)h(od(p't%uA%y%m %b'%o.%l5%Lexemem%rM%rT%o[%gb%ai%tp%ew%GeneralCategorySumSTa&m&od&r%e:&i%n%g%Stringc&r%e%p%DataRepo&n&s&t$&r+& ConstrRepfU&pF&STRepSTRefrk&ar&by&l&e&StorableSTMbS'c'r&t&e&#&State#r&a&y&STArrayk'o'v'e'r#'f*'l1'o8'w?'AsyncExceptionlZ'ea'n'pm'tt'r{' StablePtra'm'e' StableNamea'c'eO(i'n'g'c'o'm'b'i(n (i(n(g(m%(a,(r3(k:(GeneralCategoryGeneralCategorymk(er(ey(x(c(e(p(t(i(o(n( SomeExceptiono )u(t(d(o(w(n( ConsoleEventw)Shows#)ShowSe9)k@)fs)mL)oS)dZ)ea)SeekModerz)o)m)e)n)d)SeekModem)p)l)e)v)a)r) SampleVara-e!*i*g*h*t*Eithera.,cK+l*q*t<*uC*rJ*nQ*iX*n_*of*rm*dt*e{*r*ArgOrdera*u*i*r*e*o*r*d*e*r*ArgOrderr*g*ArgDescra+t +i+v+e!+s(+e/+e6+k=+SeekModec+s+u\+pc+dj+eq+rx+r+o+r+ RecUpdErrore+l+e+r+r+o+r+ RecSelErroro+n+e+r,r ,o,r, RecConErrord,l:,Realf,wR,oY,r`,lg,dn, RealWorldl,r,a,c,RealFraco,a,t, RealFloatReadm~-pJ-s;-w,r,i-t -e-m-o!-d(-e/-IOModeReadSReadPr^-ee-cl-ReadPreco-d-e-IOModet-Lexemei-o-Ration-a-l-Rationals-e.m.QSemn.QSemNa0eW0i;0o0r|.th.uN.nU.c\.Lexemero.Ptre/i2s2y 2m2b2o"2l)2GeneralCategoryuE2nL2cS2tZ2ua2ah2to2iv2o}2n2GeneralCategoryu2m2b2e2r2GeneralCategorye2t2t2e2r2GeneralCategoryd3Orde"3r)3i03n73g>3Orderinge3t\3a3d3im3ot3n{3OptDescre3s3c3r3OptDescrr3g3ArgDescrn3p3u3n3c3t3u4a 4t4i4o 4n'4GeneralCategorye6oa4uM4mT4Numax6b06m5n5r4t4a4h4i4n4g4Maybes4s4i4g4n4e4d4GeneralCategorye4p5DataRepsx5t5e!5r(5m/5i65n=5aD5tK5iR5oY5n`5NonTerminationp5a5c5i5n5g5m5a5r5k5GeneralCategorye5t5h5o5d5e5r6r 6o6r6 NoMethodErroru76f>6fE6eL6rS6iZ6na6gh6 BufferModer6g6ArgDescrs6t6e6d6a6t6o6m6i6c6a6l6l6y6NestedAtomicallya9i[9o8u[7v+7a27r97MVar#L7MVar#tb7ai7bp7lw7e~7a7b7y7t7e7a7r7r7a7y7#7MutableByteArray#r7r7a7y8#8 MutableArray#d8n*8aT8o68i=8dD8Monoidd[8Monadf8pt8l{8u8s8 MonadPlusi8x8MonadFixi8f8i8e8r8l#9s8y8m8b9o9l9GeneralCategorye*9t19t89e?9rF9GeneralCategorycb9ri9op9Microt9y9b9e9Maybeh9s9y9m9b9o9l9GeneralCategorya{<e;i ;o:g:s~:w:e:r#:c*:a1:s8:e?:lF:eM:tT:t[:eb:ri:GeneralCategorys:o:f:p:r:e:c:i:s:i:o:n:ArithExceptiono:f:f: ConsoleEventm;n;e ;by;s,;e3;p:;aA;rH;aO;tV;o];rd;GeneralCategoryu;f;f;e;r;i;n;g; BufferModei;t;Limitfh<t<x;e;m;e<Lexemet<e"<r)<n0<u7<m><bE<eL<rS<GeneralCategoryto<Eithers<t<Lastl<e<i<s<l<i<Kleisliu<s<t<Maybed Ag@n>o=p=s#=x=Ixcd=s/=t6=r==iD=nK=gR=IsStringhk=ar=ry=IsCharr=IPrIOe=m=r=e=f=IORefo=d=e=IOModerL>x>c >e>p>t">i)>o0>n7> IOExceptionrS>oZ>ra>IOErrortw>y~>p>e> IOErrorTypeds@fY@i@t>Int #?1?3?6?8?cu?e*?p ?r>e>p>DataRept?r?IntPtrg1?e]?r=?aD?lK?Integralrd?Integero|?n?s?t?r? ConstrRepInt84?Int642?Int326?Int16Int#t @i@a@l!@q(@u/@o6@t=@eD@GeneralCategoryi`@xg@Fixityez@x@o@u@t@o@f@b@o@u@n@d@s@ArrayExceptionn@o@r@e@HandlereAnAt ALexemeaAeAp=ArDAiKAnRAtYAf`AtgAynApuAe|A HPrintfTypeaApAoAvAeArAfAlAoAwAAsyncExceptionnBsAhYBrBe BsBoBlBu&Bt-Bi4Bo;BnBB HasResolutiont`BagBbnBluBe|B HashTabledBlBeBHandlepBrBHandleroBsBnB HandlePosneBnCe CrCaCl"Cc)Ca0Ct7Ce>CgECoLCrSCyZCGeneralCategorydoGiwElDo6DrCuCnCcCpCtCrCFunPtrtCoCrCFunctoraCcCtCiDo DnDaDl"D FractionallDrBDeqDmNDaUDt\DGeneralCategoryixDgDnDpDtDrD ForeignPtrdDaDbDlDeDFoldableoDaDtDcEEi%Er EeEpEDataRepn,Eg3EFloatingoLEnSEsZEtaErhE ConstrReplFnErExEeEiEtEyEFixitydEFixedsEtEFirstaElEi5FqFu FoFtFe FGeneralCategoryzTCModedYUl4Uo^TcTnTsoTevT ConsoleEventpTuTnTcTtTuTaTtTiToTnTGeneralCategorygTCLongkUt UiUcUk!U ClockTicko;UnBUgIUCLLongo`UugUbnUluUe|UCLDoublemUpUbUuUfUCJmpBufnUo+VtUCIntm VpUtUrUCIntPtraVxVCIntMaxCInoa@VnZVrLVCharChaniVlVpyVoVsVCFposoVaVtVCFloatlVeVCFileeWoVuVbVlVeWCDoublevWCDevhWWl2Wo9Wc@WkGWCClocka^WreWCChart{WcWeWgWoWrWyWCategoryhWHandleri[lXoXryXu-XyWtWeWcWoXu XnXtX ByteCountf4Xf;XeBXrIXmPXoWXd^XeeX BufferModeeXaXkX ConsoleEventoXuXnXdXeXdXBoundedlXBooloXcXkYb[eLYrYeYa"Ys)Yo0Yn7Y BlockReasondSYi2[o_YnfYbZdZeTZfYmYoYsYtYmY BlockReasontYhYeYrY BlockReasonvYaYrY BlockReasonoZr ZeZiZg Zn'Zc.Za5Zl?FilePath2Eo/oonnn]n1n nmmumKm!mmllulWl+lkkkk_k?kkjjj}jgj9j jiiuiEi!ihhh{hMh%hgggg[gAgwindowsMgWindows takefilenamelg takeFileNamebctakeextensionsgtakeExtensions`a takeextensiong takeExtension^_ takedriveg takeDrive\] takedirectory h takeDirectoryZ[ takebasename6h takeBaseNameXYsplitsearchpathahsplitSearchPathVW splitpathh splitPathTU splitfilenameh splitFileNameRSsplitextensionshsplitExtensionsPQsplitextensionisplitExtensionNO splitdrive0i splitDriveLMsplitdirectoriesZisplitDirectoriesJKsearchpathseparatorisearchPathSeparatorHIreplacefilenameireplaceFileNameFGreplaceextensionireplaceExtensionDEreplacedirectoryjreplaceDirectoryBCreplacebasenameMjreplaceBaseName@AposixqjPosixpathseparatorsjpathSeparators>? pathseparatorj pathSeparator<= normalisej normalise:; makevalidk makeValid89 makerelative(k makeRelative67joinpathLkjoinPath45 joindrivemk joinDrive23isvalidkisValid01issearchpathseparatorkisSearchPathSeparator./ isrelativek isRelative,-ispathseparatorlisPathSeparator*+isextseparator>lisExtSeparator()isdriveclisDrive&' isabsolutel isAbsolute$%hastrailingpathseparatorlhasTrailingPathSeparator"# hasextensionl hasExtension !hasdrivemhasDrive getsearchpath3m getSearchPathfilepathXmFilePathfilepath extseparatorm extSeparator equalfilepathm equalFilePathdroptrailingpathseparatormdropTrailingPathSeparator dropfilenamen dropFileNamedropextensionsDndropExtensions dropextensionon dropExtension dropdriven dropDrivecombinencombine addtrailingpathseparatornaddTrailingPathSeparator addextensiono addExtension 7o<.>Mo<.>cE7gInDi8G)Yc=U[QGwYB+5?iK ϭܬj٦5Oige̝3|Ŕq-ƒWK~'|zJyxwuttrp takeFileName takeFileName :: FilePath -> FilePath[qDqFilePathFilePath&Get the file name.
takeFileName "test/" == ""
takeFileName x `isSuffixOf` x
takeFileName x == snd (splitFileName x)
Valid x => takeFileName (replaceFileName x "fred") == "fred"
Valid x => takeFileName (x </> "fred") == "fred"
Valid x => isRelative (takeFileName x)
 takeFileName takeFileName :: FilePath -> FilePathrrFilePathFilePath&Get the file name.
takeFileName "test/" == ""
takeFileName x `isSuffixOf` x
takeFileName x == snd (splitFileName x)
Valid x => takeFileName (replaceFileName x "fred") == "fred"
Valid x => takeFileName (x </> "fred") == "fred"
Valid x => isRelative (takeFileName x)
takeExtensionstakeExtensions :: FilePath -> StringtrtFilePathStringKGet all extensions
takeExtensions "file.tar.gz" == ".tar.gz"
takeExtensionstakeExtensions :: FilePath -> StringBu-uFilePathStringKGet all extensions
takeExtensions "file.tar.gz" == ".tar.gz"
 takeExtension takeExtension :: FilePath -> StringuuFilePathStringGet the extension of a file, returns "" for no extension, .ext otherwise.
takeExtension x == snd (splitExtension x)
Valid x => takeExtension (addExtension x "ext") == ".ext"
Valid x => takeExtension (replaceExtension x "ext") == ".ext"
 takeExtension takeExtension :: FilePath -> String{wfwFilePathStringGet the extension of a file, returns "" for no extension, .ext otherwise.
takeExtension x == snd (splitExtension x)
Valid x => takeExtension (addExtension x "ext") == ".ext"
Valid x => takeExtension (replaceExtension x "ext") == ".ext"
 takeDrive takeDrive :: FilePath -> FilePathxxFilePathFilePathOGet the drive from a filepath.
takeDrive x == fst (splitDrive x)
 takeDrive takeDrive :: FilePath -> FilePathyyFilePathFilePathOGet the drive from a filepath.
takeDrive x == fst (splitDrive x)
 takeDirectory takeDirectory :: FilePath -> FilePathqzZzFilePathFilePathGet the directory name, move up one level.
          takeDirectory x `isPrefixOf` x
          takeDirectory "foo" == ""
          takeDirectory "/foo/bar/baz" == "/foo/bar"
          takeDirectory "/foo/bar/baz/" == "/foo/bar/baz"
          takeDirectory "foo/bar/baz" == "foo/bar"
Windows:  takeDirectory "foo\\bar" == "foo"
Windows:  takeDirectory "foo\\bar\\\\" == "foo\\bar"
Windows:  takeDirectory "C:\\" == "C:\\"
 takeDirectory takeDirectory :: FilePath -> FilePath|~|FilePathFilePathGet the directory name, move up one level.
          takeDirectory x `isPrefixOf` x
          takeDirectory "foo" == ""
          takeDirectory "/foo/bar/baz" == "/foo/bar"
          takeDirectory "/foo/bar/baz/" == "/foo/bar/baz"
          takeDirectory "foo/bar/baz" == "foo/bar"
Windows:  takeDirectory "foo\\bar" == "foo"
Windows:  takeDirectory "foo\\bar\\\\" == "foo\\bar"
Windows:  takeDirectory "C:\\" == "C:\\"
 takeBaseName takeBaseName :: FilePath -> String~~FilePathStringGet the base name, without an extension or path.
takeBaseName "file/test.txt" == "test"
takeBaseName "dave.ext" == "dave"
takeBaseName "" == ""
takeBaseName "test" == "test"
takeBaseName (addTrailingPathSeparator x) == ""
takeBaseName "file/file.tar.gz" == "file.tar"
 takeBaseName takeBaseName :: FilePath -> String9$FilePathStringGet the base name, without an extension or path.
takeBaseName "file/test.txt" == "test"
takeBaseName "dave.ext" == "dave"
takeBaseName "" == ""
takeBaseName "test" == "test"
takeBaseName (addTrailingPathSeparator x) == ""
takeBaseName "file/file.tar.gz" == "file.tar"
splitSearchPathsplitSearchPath :: String ->  [FilePath]́String[]FilePathTake a string, split it on the searchPathSeparator character. Follows the recommendations in http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html
Posix:   splitSearchPath "File1:File2:File3"  == ["File1","File2","File3"]
Posix:   splitSearchPath "File1::File2:File3" == ["File1",".","File2","File3"]
Windows: splitSearchPath "File1;File2;File3"  == ["File1","File2","File3"]
Windows: splitSearchPath "File1;;File2;File3" == ["File1","File2","File3"]
splitSearchPathsplitSearchPath :: String ->  [FilePath]8String[]FilePathTake a string, split it on the searchPathSeparator character. Follows the recommendations in http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html
Posix:   splitSearchPath "File1:File2:File3"  == ["File1","File2","File3"]
Posix:   splitSearchPath "File1::File2:File3" == ["File1",".","File2","File3"]
Windows: splitSearchPath "File1;File2;File3"  == ["File1","File2","File3"]
Windows: splitSearchPath "File1;;File2;File3" == ["File1","File2","File3"]
 splitPath splitPath :: FilePath ->  [FilePath]~FilePath[]FilePathASplit a path by the directory separator.
concat (splitPath x) == x
splitPath "test//item/" == ["test//","item/"]
splitPath "test/item/file" == ["test/","item/","file"]
splitPath "" == []
Windows: splitPath "c:\\test\\path" == ["c:\\","test\\","path"]
Posix:   splitPath "/file/test" == ["/","file/","test"]
 splitPath splitPath :: FilePath ->  [FilePath]N1FilePath[]FilePathASplit a path by the directory separator.
concat (splitPath x) == x
splitPath "test//item/" == ["test//","item/"]
splitPath "test/item/file" == ["test/","item/","file"]
splitPath "" == []
Windows: splitPath "c:\\test\\path" == ["c:\\","test\\","path"]
Posix:   splitPath "/file/test" == ["/","file/","test"]
 splitFileName splitFileName :: FilePath -> (String, String)FilePath(,)StringStringSplit a filename into directory and file. combine is the inverse.
uncurry (++) (splitFileName x) == x
Valid x => uncurry combine (splitFileName x) == x
splitFileName "file/bob.txt" == ("file/", "bob.txt")
splitFileName "file/" == ("file/", "")
splitFileName "bob" == ("", "bob")
Posix:   splitFileName "/" == ("/","")
Windows: splitFileName "c:" == ("c:","")
 splitFileName splitFileName :: FilePath -> (String, String)FilePath(,)StringStringSplit a filename into directory and file. combine is the inverse.
uncurry (++) (splitFileName x) == x
Valid x => uncurry combine (splitFileName x) == x
splitFileName "file/bob.txt" == ("file/", "bob.txt")
splitFileName "file/" == ("file/", "")
splitFileName "bob" == ("", "bob")
Posix:   splitFileName "/" == ("/","")
Windows: splitFileName "c:" == ("c:","")
splitExtensionssplitExtensions :: FilePath -> (FilePath, String)*FilePath(,)FilePathStringZSplit on all extensions
splitExtensions "file.tar.gz" == ("file",".tar.gz")
splitExtensionssplitExtensions :: FilePath -> (FilePath, String)FilePath(,)FilePathStringZSplit on all extensions
splitExtensions "file.tar.gz" == ("file",".tar.gz")
splitExtensionsplitExtension :: FilePath -> (String, String)ҏFilePath(,)StringString!Split on the extension. addExtension is the inverse.
uncurry (++) (splitExtension x) == x
uncurry addExtension (splitExtension x) == x
splitExtension "file.txt" == ("file",".txt")
splitExtension "file" == ("file","")
splitExtension "file/file.txt" == ("file/file",".txt")
splitExtension "file.txt/boris" == ("file.txt/boris","")
splitExtension "file.txt/boris.ext" == ("file.txt/boris",".ext")
splitExtension "file/path.txt.bob.fred" == ("file/path.txt.bob",".fred")
splitExtension "file/path.txt/" == ("file/path.txt/","")
splitExtensionsplitExtension :: FilePath -> (String, String)|FilePath(,)StringString!Split on the extension. addExtension is the inverse.
uncurry (++) (splitExtension x) == x
uncurry addExtension (splitExtension x) == x
splitExtension "file.txt" == ("file",".txt")
splitExtension "file" == ("file","")
splitExtension "file/file.txt" == ("file/file",".txt")
splitExtension "file.txt/boris" == ("file.txt/boris","")
splitExtension "file.txt/boris.ext" == ("file.txt/boris",".ext")
splitExtension "file/path.txt.bob.fred" == ("file/path.txt.bob",".fred")
splitExtension "file/path.txt/" == ("file/path.txt/","")
 splitDrive splitDrive :: FilePath -> (FilePath, FilePath)J"FilePath(,)FilePathFilePath.Split a path into a drive and a path. On Unix, / is a Drive.
uncurry (++) (splitDrive x) == x
Windows: splitDrive "file" == ("","file")
Windows: splitDrive "c:/file" == ("c:/","file")
Windows: splitDrive "c:\\file" == ("c:\\","file")
Windows: splitDrive "\\\\shared\\test" == ("\\\\shared\\","test")
Windows: splitDrive "\\\\shared" == ("\\\\shared","")
Windows: splitDrive "\\\\?\\UNC\\shared\\file" == ("\\\\?\\UNC\\shared\\","file")
Windows: splitDrive "\\\\?\\UNCshared\\file" == ("\\\\?\\","UNCshared\\file")
Windows: splitDrive "\\\\?\\d:\\file" == ("\\\\?\\d:\\","file")
Windows: splitDrive "/d" == ("","/d")
Posix:   splitDrive "/test" == ("/","test")
Posix:   splitDrive "//test" == ("//","test")
Posix:   splitDrive "test/file" == ("","test/file")
Posix:   splitDrive "file" == ("","file")
 splitDrive splitDrive :: FilePath -> (FilePath, FilePath)٘FilePath(,)FilePathFilePath.Split a path into a drive and a path. On Unix, / is a Drive.
uncurry (++) (splitDrive x) == x
Windows: splitDrive "file" == ("","file")
Windows: splitDrive "c:/file" == ("c:/","file")
Windows: splitDrive "c:\\file" == ("c:\\","file")
Windows: splitDrive "\\\\shared\\test" == ("\\\\shared\\","test")
Windows: splitDrive "\\\\shared" == ("\\\\shared","")
Windows: splitDrive "\\\\?\\UNC\\shared\\file" == ("\\\\?\\UNC\\shared\\","file")
Windows: splitDrive "\\\\?\\UNCshared\\file" == ("\\\\?\\","UNCshared\\file")
Windows: splitDrive "\\\\?\\d:\\file" == ("\\\\?\\d:\\","file")
Windows: splitDrive "/d" == ("","/d")
Posix:   splitDrive "/test" == ("/","test")
Posix:   splitDrive "//test" == ("//","test")
Posix:   splitDrive "test/file" == ("","test/file")
Posix:   splitDrive "file" == ("","file")
splitDirectoriessplitDirectories :: FilePath ->  [FilePath]FilePath[]FilePathJust as splitPath, but don't add the trailing slashes to each element.
splitDirectories "test/file" == ["test","file"]
splitDirectories "/test/file" == ["/","test","file"]
Valid x => joinPath (splitDirectories x) `equalFilePath` x
splitDirectories "" == []
splitDirectoriessplitDirectories :: FilePath ->  [FilePath]H+FilePath[]FilePathJust as splitPath, but don't add the trailing slashes to each element.
splitDirectories "test/file" == ["test","file"]
splitDirectories "/test/file" == ["/","test","file"]
Valid x => joinPath (splitDirectories x) `equalFilePath` x
splitDirectories "" == []
searchPathSeparatorsearchPathSeparator :: CharCharThe character that is used to separate the entries in the $PATH environment variable.
Windows: searchPathSeparator == ';'
Posix:   searchPathSeparator == ':'
searchPathSeparatorsearchPathSeparator :: CharCharThe character that is used to separate the entries in the $PATH environment variable.
Windows: searchPathSeparator == ';'
Posix:   searchPathSeparator == ':'
replaceFileNamereplaceFileName :: FilePath -> String -> FilePath֡FilePathStringFilePathVSet the filename.
Valid x => replaceFileName x (takeFileName x) == x
replaceFileNamereplaceFileName :: FilePath -> String -> FilePathۢFilePathStringFilePathVSet the filename.
Valid x => replaceFileName x (takeFileName x) == x
replaceExtensionreplaceExtension :: FilePath -> String -> FilePathãFilePathStringFilePath@Set the extension of a file, overwriting one if already present.
replaceExtension "file.txt" ".bob" == "file.bob"
replaceExtension "file.txt" "bob" == "file.bob"
replaceExtension "file" ".bob" == "file.bob"
replaceExtension "file.txt" "" == "file"
replaceExtension "file.fred.bob" "txt" == "file.fred.txt"
replaceExtensionreplaceExtension :: FilePath -> String -> FilePathvFilePathStringFilePath@Set the extension of a file, overwriting one if already present.
replaceExtension "file.txt" ".bob" == "file.bob"
replaceExtension "file.txt" "bob" == "file.bob"
replaceExtension "file" ".bob" == "file.bob"
replaceExtension "file.txt" "" == "file"
replaceExtension "file.fred.bob" "txt" == "file.fred.txt"
replaceDirectoryreplaceDirectory :: FilePath -> String -> FilePathgHFilePathStringFilePathwSet the directory, keeping the filename the same.
replaceDirectory x (takeDirectory x) `equalFilePath` x
replaceDirectoryreplaceDirectory :: FilePath -> String -> FilePathpQFilePathStringFilePathwSet the directory, keeping the filename the same.
replaceDirectory x (takeDirectory x) `equalFilePath` x
replaceBaseNamereplaceBaseName :: FilePath -> String -> FilePathwXFilePathStringFilePathSet the base name.
replaceBaseName "file/test.txt" "bob" == "file/bob.txt"
replaceBaseName "fred" "bill" == "bill"
replaceBaseName "/dave/fred/bob.gz.tar" "new" == "/dave/fred/new.tar"
replaceBaseName x (takeBaseName x) == x
replaceBaseNamereplaceBaseName :: FilePath -> String -> FilePathתFilePathStringFilePathSet the base name.
replaceBaseName "file/test.txt" "bob" == "file/bob.txt"
replaceBaseName "fred" "bill" == "bill"
replaceBaseName "/dave/fred/bob.gz.tar" "new" == "/dave/fred/new.tar"
replaceBaseName x (takeBaseName x) == x
pathSeparatorspathSeparators :: [Char]9,[]CharThe list of all possible separators.
Windows: pathSeparators == ['\\', '/']
Posix:   pathSeparators == ['/']
pathSeparator `elem` pathSeparators
pathSeparatorspathSeparators :: [Char],[]CharThe list of all possible separators.
Windows: pathSeparators == ['\\', '/']
Posix:   pathSeparators == ['/']
pathSeparator `elem` pathSeparators
 pathSeparator pathSeparator :: CharCharThe character that separates directories. In the case where more than one character is possible, pathSeparator is the 'ideal' one.
Windows: pathSeparator == '\\'
Posix:   pathSeparator ==  '/'
isPathSeparator pathSeparator
 pathSeparator pathSeparator :: CharSLCharThe character that separates directories. In the case where more than one character is possible, pathSeparator is the 'ideal' one.
Windows: pathSeparator == '\\'
Posix:   pathSeparator ==  '/'
isPathSeparator pathSeparator
 normalise normalise :: FilePath -> FilePathFilePathFilePathNormalise a file
Posix:   normalise "/file/\\test////" == "/file/\\test/"
Posix:   normalise "/file/./test" == "/file/test"
Posix:   normalise "/test/file/../bob/fred/" == "/test/file/../bob/fred/"
Posix:   normalise "../bob/fred/" == "../bob/fred/"
Posix:   normalise "./bob/fred/" == "bob/fred/"
Windows: normalise "c:\\file/bob\\" == "C:\\file\\bob\\"
Windows: normalise "c:\\" == "C:\\"
Windows: normalise "\\\\server\\test" == "\\\\server\\test"
Windows: normalise "c:/file" == "C:\\file"
         normalise "." == "."
Posix:   normalise "./" == "./"
 normalise normalise :: FilePath -> FilePathϳFilePathFilePathNormalise a file
Posix:   normalise "/file/\\test////" == "/file/\\test/"
Posix:   normalise "/file/./test" == "/file/test"
Posix:   normalise "/test/file/../bob/fred/" == "/test/file/../bob/fred/"
Posix:   normalise "../bob/fred/" == "../bob/fred/"
Posix:   normalise "./bob/fred/" == "bob/fred/"
Windows: normalise "c:\\file/bob\\" == "C:\\file\\bob\\"
Windows: normalise "c:\\" == "C:\\"
Windows: normalise "\\\\server\\test" == "\\\\server\\test"
Windows: normalise "c:/file" == "C:\\file"
         normalise "." == "."
Posix:   normalise "./" == "./"
 makeValid makeValid :: FilePath -> FilePathֶFilePathFilePathTake a FilePath and make it valid; does not change already valid FilePaths.
isValid (makeValid x)
isValid x ==> makeValid x == x
makeValid "" == "_"
Windows: makeValid "c:\\test:of_test" == "c:\\test_of_test"
Windows: makeValid "test*" == "test_"
Windows: makeValid "c:\\test\\nul" == "c:\\test\\nul_"
Windows: makeValid "c:\\test\\prn.txt" == "c:\\test\\prn_.txt"
Windows: makeValid "c:\\test/prn.txt" == "c:\\test/prn_.txt"
Windows: makeValid "c:\\nul\\file" == "c:\\nul_\\file"
 makeValid makeValid :: FilePath -> FilePathI2FilePathFilePathTake a FilePath and make it valid; does not change already valid FilePaths.
isValid (makeValid x)
isValid x ==> makeValid x == x
makeValid "" == "_"
Windows: makeValid "c:\\test:of_test" == "c:\\test_of_test"
Windows: makeValid "test*" == "test_"
Windows: makeValid "c:\\test\\nul" == "c:\\test\\nul_"
Windows: makeValid "c:\\test\\prn.txt" == "c:\\test\\prn_.txt"
Windows: makeValid "c:\\test/prn.txt" == "c:\\test/prn_.txt"
Windows: makeValid "c:\\nul\\file" == "c:\\nul_\\file"
 makeRelative makeRelative :: FilePath -> FilePath -> FilePathɻFilePathFilePathFilePathhContract a filename, based on a relative path. There is no corresponding makeAbsolute function, instead use System.Directory.canonicalizePath which has the same effect.
         Valid y => equalFilePath x y || (isRelative x && makeRelative y x == x) || equalFilePath (y </> makeRelative y x) x
         makeRelative x x == "."
         null y || equalFilePath (makeRelative x (x </> y)) y || null (takeFileName x)
Windows: makeRelative "C:\\Home" "c:\\home\\bob" == "bob"
Windows: makeRelative "C:\\Home" "c:/home/bob" == "bob"
Windows: makeRelative "C:\\Home" "D:\\Home\\Bob" == "D:\\Home\\Bob"
Windows: makeRelative "C:\\Home" "C:Home\\Bob" == "C:Home\\Bob"
Windows: makeRelative "/Home" "/home/bob" == "bob"
Posix:   makeRelative "/Home" "/home/bob" == "/home/bob"
Posix:   makeRelative "/home/" "/home/bob/foo/bar" == "bob/foo/bar"
Posix:   makeRelative "/fred" "bob" == "bob"
Posix:   makeRelative "/file/test" "/file/test/fred" == "fred"
Posix:   makeRelative "/file/test" "/file/test/fred/" == "fred/"
Posix:   makeRelative "some/path" "some/path/a/b/c" == "a/b/c"
 makeRelative makeRelative :: FilePath -> FilePath -> FilePathFilePathFilePathFilePathhContract a filename, based on a relative path. There is no corresponding makeAbsolute function, instead use System.Directory.canonicalizePath which has the same effect.
         Valid y => equalFilePath x y || (isRelative x && makeRelative y x == x) || equalFilePath (y </> makeRelative y x) x
         makeRelative x x == "."
         null y || equalFilePath (makeRelative x (x </> y)) y || null (takeFileName x)
Windows: makeRelative "C:\\Home" "c:\\home\\bob" == "bob"
Windows: makeRelative "C:\\Home" "c:/home/bob" == "bob"
Windows: makeRelative "C:\\Home" "D:\\Home\\Bob" == "D:\\Home\\Bob"
Windows: makeRelative "C:\\Home" "C:Home\\Bob" == "C:Home\\Bob"
Windows: makeRelative "/Home" "/home/bob" == "bob"
Posix:   makeRelative "/Home" "/home/bob" == "/home/bob"
Posix:   makeRelative "/home/" "/home/bob/foo/bar" == "bob/foo/bar"
Posix:   makeRelative "/fred" "bob" == "bob"
Posix:   makeRelative "/file/test" "/file/test/fred" == "fred"
Posix:   makeRelative "/file/test" "/file/test/fred/" == "fred/"
Posix:   makeRelative "some/path" "some/path/a/b/c" == "a/b/c"
joinPathjoinPath ::  [FilePath] -> FilePathz[]FilePathFilePathJoin path elements back together.
Valid x => joinPath (splitPath x) == x
joinPath [] == ""
Posix: joinPath ["test","file","path"] == "test/file/path"
joinPathjoinPath ::  [FilePath] -> FilePath[]FilePathFilePathJoin path elements back together.
Valid x => joinPath (splitPath x) == x
joinPath [] == ""
Posix: joinPath ["test","file","path"] == "test/file/path"
 joinDrive joinDrive :: FilePath -> FilePath -> FilePathFilePathFilePathFilePathJoin a drive and the rest of the path.
         uncurry joinDrive (splitDrive x) == x
Windows: joinDrive "C:" "foo" == "C:foo"
Windows: joinDrive "C:\\" "bar" == "C:\\bar"
Windows: joinDrive "\\\\share" "foo" == "\\\\share\\foo"
Windows: joinDrive "/:" "foo" == "/:\\foo"
 joinDrive joinDrive :: FilePath -> FilePath -> FilePathbFilePathFilePathFilePathJoin a drive and the rest of the path.
         uncurry joinDrive (splitDrive x) == x
Windows: joinDrive "C:" "foo" == "C:foo"
Windows: joinDrive "C:\\" "bar" == "C:\\bar"
Windows: joinDrive "\\\\share" "foo" == "\\\\share\\foo"
Windows: joinDrive "/:" "foo" == "/:\\foo"
isValidisValid :: FilePath -> BoolFilePathBoolIs a FilePath valid, i.e. could you create a file like it?
         isValid "" == False
Posix:   isValid "/random_ path:*" == True
Posix:   isValid x == not (null x)
Windows: isValid "c:\\test" == True
Windows: isValid "c:\\test:of_test" == False
Windows: isValid "test*" == False
Windows: isValid "c:\\test\\nul" == False
Windows: isValid "c:\\test\\prn.txt" == False
Windows: isValid "c:\\nul\\file" == False
Windows: isValid "\\\\" == False
isValidisValid :: FilePath -> Bool'FilePathBoolIs a FilePath valid, i.e. could you create a file like it?
         isValid "" == False
Posix:   isValid "/random_ path:*" == True
Posix:   isValid x == not (null x)
Windows: isValid "c:\\test" == True
Windows: isValid "c:\\test:of_test" == False
Windows: isValid "test*" == False
Windows: isValid "c:\\test\\nul" == False
Windows: isValid "c:\\test\\prn.txt" == False
Windows: isValid "c:\\nul\\file" == False
Windows: isValid "\\\\" == False
isSearchPathSeparatorisSearchPathSeparator :: Char -> BoolcTCharBoolgIs the character a file separator?
isSearchPathSeparator a == (a == searchPathSeparator)
isSearchPathSeparatorisSearchPathSeparator :: Char -> Bool<-CharBoolgIs the character a file separator?
isSearchPathSeparator a == (a == searchPathSeparator)
 isRelative isRelative :: FilePath -> BoolFilePathBoollIs a path relative, or is it fixed to the root?
Windows: isRelative "path\\test" == True
Windows: isRelative "c:\\test" == False
Windows: isRelative "c:test" == True
Windows: isRelative "c:" == True
Windows: isRelative "\\\\foo" == False
Windows: isRelative "/foo" == True
Posix:   isRelative "test/path" == True
Posix:   isRelative "/test" == False
 isRelative isRelative :: FilePath -> BoolFilePathBoollIs a path relative, or is it fixed to the root?
Windows: isRelative "path\\test" == True
Windows: isRelative "c:\\test" == False
Windows: isRelative "c:test" == True
Windows: isRelative "c:" == True
Windows: isRelative "\\\\foo" == False
Windows: isRelative "/foo" == True
Posix:   isRelative "test/path" == True
Posix:   isRelative "/test" == False
isPathSeparatorisPathSeparator :: Char -> BoolCharBoolRather than using (== pathSeparator), use this. Test if something is a path separator.
isPathSeparator a == (a `elem` pathSeparators)
isPathSeparatorisPathSeparator :: Char -> BoolCharBoolRather than using (== pathSeparator), use this. Test if something is a path separator.
isPathSeparator a == (a `elem` pathSeparators)
isExtSeparatorisExtSeparator :: Char -> BoolCharBool_Is the character an extension character?
isExtSeparator a == (a == extSeparator)
isExtSeparatorisExtSeparator :: Char -> Bool~oCharBool_Is the character an extension character?
isExtSeparator a == (a == extSeparator)
isDriveisDrive :: FilePath -> Bool;(FilePathBoolIs an element a drive isDriveisDrive :: FilePath -> BoolFilePathBoolIs an element a drive  isAbsolute isAbsolute :: FilePath -> Bool)FilePathBoolV
not . isRelative
isAbsolute x == not (isRelative x)
 isAbsolute isAbsolute :: FilePath -> BoolFilePathBoolV
not . isRelative
isAbsolute x == not (isRelative x)
hasTrailingPathSeparatorhasTrailingPathSeparator :: FilePath -> BoolFilePathBoolIs an item either a directory or the last character a path separator?
hasTrailingPathSeparator "test" == False
hasTrailingPathSeparator "test/" == True
hasTrailingPathSeparatorhasTrailingPathSeparator :: FilePath -> BoolFilePathBoolIs an item either a directory or the last character a path separator?
hasTrailingPathSeparator "test" == False
hasTrailingPathSeparator "test/" == True
 hasExtension hasExtension :: FilePath -> BoolFilePathBoolhDoes the given filename have an extension?
null (takeExtension x) == not (hasExtension x)
 hasExtension hasExtension :: FilePath -> BoolFilePathBoolhDoes the given filename have an extension?
null (takeExtension x) == not (hasExtension x)
hasDrivehasDrive :: FilePath -> BoolrFilePathBoolODoes a path have a drive.
not (hasDrive x) == null (takeDrive x)
hasDrivehasDrive :: FilePath -> Bool4!FilePathBoolODoes a path have a drive.
not (hasDrive x) == null (takeDrive x)
 getSearchPath getSearchPath ::  IO [FilePath]IO[]FilePath&Get a list of filepaths in the $PATH.  getSearchPath getSearchPath ::  IO [FilePath]oXIO[]FilePath&Get a list of filepaths in the $PATH.  extSeparator extSeparator :: CharChar;File extension character
extSeparator == '.'
 extSeparator extSeparator :: Char`YChar;File extension character
extSeparator == '.'
 equalFilePath equalFilePath :: FilePath -> FilePath -> Bool#FilePathFilePathBoolEquality of two FilePaths. If you call System.Directory.canonicalizePath first this has a much better chance of working. Note that this doesn't follow symlinks or DOSNAM~1s.
         x == y ==> equalFilePath x y
         normalise x == normalise y ==> equalFilePath x y
Posix:   equalFilePath "foo" "foo/"
Posix:   not (equalFilePath "foo" "/foo")
Posix:   not (equalFilePath "foo" "FOO")
Windows: equalFilePath "foo" "FOO"
 equalFilePath equalFilePath :: FilePath -> FilePath -> BoolwZFilePathFilePathBoolEquality of two FilePaths. If you call System.Directory.canonicalizePath first this has a much better chance of working. Note that this doesn't follow symlinks or DOSNAM~1s.
         x == y ==> equalFilePath x y
         normalise x == normalise y ==> equalFilePath x y
Posix:   equalFilePath "foo" "foo/"
Posix:   not (equalFilePath "foo" "/foo")
Posix:   not (equalFilePath "foo" "FOO")
Windows: equalFilePath "foo" "FOO"
dropTrailingPathSeparatordropTrailingPathSeparator :: FilePath -> FilePathFilePathFilePathRemove any trailing path separators
dropTrailingPathSeparator "file/test/" == "file/test"
not (hasTrailingPathSeparator (dropTrailingPathSeparator x)) || isDrive x
Posix:    dropTrailingPathSeparator "/" == "/"
Windows:  dropTrailingPathSeparator "\\" == "\\"
dropTrailingPathSeparatordropTrailingPathSeparator :: FilePath -> FilePathiRFilePathFilePathRemove any trailing path separators
dropTrailingPathSeparator "file/test/" == "file/test"
not (hasTrailingPathSeparator (dropTrailingPathSeparator x)) || isDrive x
Posix:    dropTrailingPathSeparator "/" == "/"
Windows:  dropTrailingPathSeparator "\\" == "\\"
 dropFileName dropFileName :: FilePath -> FilePathFilePathFilePathIDrop the filename.
dropFileName x == fst (splitFileName x)
 dropFileName dropFileName :: FilePath -> FilePathFilePathFilePathIDrop the filename.
dropFileName x == fst (splitFileName x)
dropExtensionsdropExtensions :: FilePath -> FilePathaJFilePathFilePathHDrop all extensions
not $ hasExtension (dropExtensions x)
dropExtensionsdropExtensions :: FilePath -> FilePathFilePathFilePathHDrop all extensions
not $ hasExtension (dropExtensions x)
 dropExtension dropExtension :: FilePath -> FilePathFilePathFilePathiRemove last extension, and the "." preceding it.
dropExtension x == fst (splitExtension x)
 dropExtension dropExtension :: FilePath -> FilePathFilePathFilePathiRemove last extension, and the "." preceding it.
dropExtension x == fst (splitExtension x)
 dropDrive dropDrive :: FilePath -> FilePathnFilePathFilePathPDelete the drive, if it exists.
dropDrive x == snd (splitDrive x)
 dropDrive dropDrive :: FilePath -> FilePath?(FilePathFilePathPDelete the drive, if it exists.
dropDrive x == snd (splitDrive x)
combinecombine :: FilePath -> FilePath -> FilePathFilePathFilePathFilePathWCombine two paths, if the second path isAbsolute, then it returns the second.
Valid x => combine (takeDirectory x) (takeFileName x) `equalFilePath` x
Posix:   combine "/" "test" == "/test"
Posix:   combine "home" "bob" == "home/bob"
Windows: combine "home" "bob" == "home\\bob"
Windows: combine "home" "/bob" == "/bob"
combinecombine :: FilePath -> FilePath -> FilePathFilePathFilePathFilePathWCombine two paths, if the second path isAbsolute, then it returns the second.
Valid x => combine (takeDirectory x) (takeFileName x) `equalFilePath` x
Posix:   combine "/" "test" == "/test"
Posix:   combine "home" "bob" == "home/bob"
Windows: combine "home" "bob" == "home\\bob"
Windows: combine "home" "/bob" == "/bob"
addTrailingPathSeparatoraddTrailingPathSeparator :: FilePath -> FilePathFilePathFilePathAdd a trailing file path separator if one is not already present.
hasTrailingPathSeparator (addTrailingPathSeparator x)
hasTrailingPathSeparator x ==> addTrailingPathSeparator x == x
Posix:    addTrailingPathSeparator "test/rest" == "test/rest/"
addTrailingPathSeparatoraddTrailingPathSeparator :: FilePath -> FilePath\EFilePathFilePathAdd a trailing file path separator if one is not already present.
hasTrailingPathSeparator (addTrailingPathSeparator x)
hasTrailingPathSeparator x ==> addTrailingPathSeparator x == x
Posix:    addTrailingPathSeparator "test/rest" == "test/rest/"
 addExtension addExtension :: FilePath -> String -> FilePathFilePathStringFilePathAdd an extension, even if there is already one there. E.g. addExtension "foo.txt" "bat" -> "foo.txt.bat".
addExtension "file.txt" "bib" == "file.txt.bib"
addExtension "file." ".bib" == "file..bib"
addExtension "file" ".bib" == "file.bib"
addExtension "/" "x" == "/.x"
Valid x => takeFileName (addExtension (addTrailingPathSeparator x) "ext") == ".ext"
Windows: addExtension "\\\\share" ".txt" == "\\\\share\\.txt"
 addExtension addExtension :: FilePath -> String -> FilePath2FilePathStringFilePathAdd an extension, even if there is already one there. E.g. addExtension "foo.txt" "bat" -> "foo.txt.bat".
addExtension "file.txt" "bib" == "file.txt.bib"
addExtension "file." ".bib" == "file..bib"
addExtension "file" ".bib" == "file.bib"
addExtension "/" "x" == "/.x"
Valid x => takeFileName (addExtension (addTrailingPathSeparator x) "ext") == ".ext"
Windows: addExtension "\\\\share" ".txt" == "\\\\share\\.txt"
 () :: FilePath -> FilePath -> FilePathoNFilePathFilePathFilePath!A nice alias for combine.  () :: FilePath -> FilePath -> FilePathFilePathFilePathFilePath!A nice alias for combine. <.> (<.>) :: FilePath -> String -> FilePathFilePathStringFilePathFAlias to addExtension, for people who like that sort of thing. <.> (<.>) :: FilePath -> String -> FilePathuVFilePathStringFilePathFAlias to addExtension, for people who like that sort of thing. Windowsmodule System.FilePath.WindowsA library for FilePath manipulations, using Windows style paths on all platforms. Importing System.FilePath is usually better. Posixmodule System.FilePath.PosixA library for FilePath manipulations, using Posix style paths on all platforms. Importing System.FilePath is usually better. filepathpackage filepathp{Library for manipulating FilePath's in a cross platform way. Library for manipulating FilePath's in a cross platform way. FilePathmodule System.FilePath$ A library for FilePath manipulations, using Posix or Windows filepaths depending on the platform. Both System.FilePath.Posix and System.FilePath.Windows provide the same interface. See either for examples and a list of the available functions. jSBSystemFilePathSystemFilePathPosixSystemFilePathWindowsfilepath1.1.0.2Fhttp://hackage.haskell.org/packages/archive/filepath/1.1.0.2/doc/html/Chttp://hackage.haskell.org/cgi-bin/hackage-scripts/package/filepath