if we look at filepath documentation. this seems to me to say that you almost always should use OsPath over FilePath if the cost is the same.
As, effectively, System.IO.FilePath
is just a synonym for [Data.Char.Char]
, I am not sure if ‘deprecate’ is the correct term. In his associated blog, and elsewhere, Julian Ospald (@hasufell) has already gone the extra mile to urge people to make the change where it counts and explain the benefits of doing so. I think it is a good question to ask if the Haddock documentation for FilePath
could helpfully say a little more than it currently does. It currently says:
-- | File and directory names are values of type 'String',
-- whose precise meaning is operating system dependent. Files
-- can be opened, yielding a handle which can then be used to
-- operate on the contents of that file.
type FilePath = String
If I understand the blog correctly, this would be more accurate:
-- | File and directory names can be represented by values of type
-- 'String'. However, the precise meaning is operating system dependent.
-- (In some cases, this can cause problems and other types have been
-- developed to avoid them; see the @filepath@ package.) Files can be
-- opened, yielding a handle which can then be used to operate on the
-- contents of that file.
type FilePath = String
sure the proposed documentation change is good but why aren’t the functions and the datatype deprecated with a warning like head
?
head
is not deprecated. Also: FilePath and head are part of the Haskell report.
There are people here better placed than me to answer your question, but this is mine:
Haskell is used in a variety of contexts. In some, the problems with [Char]
that Julian’s blog post identifies are mission critical. In others, they can be considered relatively unimportant.
An important context is education. There, at least initially, it can be useful to put certain complexity to one side, in order to reveal other things more plainly.
If you are confident that you will be working in an environment where directories and filepaths will involve only ASCII characters, then the problems that Julian identifies can be put to one side.
The premise is merely that for every operation that accepts/returns a FilePath
there exists that same operation that accepts/returns an OsPath
and there’s a conversion in between. The default implicit conversion is encodeFS
/decodeFS
, so there’s no point reaching for OsPath
if that’s all you’re going to do anyway.
Also as of right now using OsPath
is excruciatingly tedious, as none of the system functions are where you expect (gotta fetch them from unix
and Win32
packages and combine with CPP), general locale encoding is in GHC.IO.Encoding
(internal module), and all the data conversions are performed at runtime (unless you use Template Haskell).
So, as with all things GHC, come back in five years, things may be different by then.
Didn’t know that existed and I don’t see getArgs
there, exciting.
Hmm yes, admittedly, I don’t think there is a getArgs version that can return OsStrings yet. I remember a ticket somewhere about some functions that were still missing for that to work / (which was being worked on). Let me see if I can find a reference somewhere.
edit: see e.g. Support for ospath/osstring · Issue #491 · pcapriotti/optparse-applicative · GitHub and the references therein.
That should be easy:
- unix/System/Posix/Env/PosixString.hsc at 4f7f16875c5e491722eda32df53a7b5c3094e4f9 · haskell/unix · GitHub
- win32/System/Win32/WindowsString/Console.hsc at 6b5bc0494e292ac122a99a8e20a8acc4bf2c7455 · haskell/win32 · GitHub
But keep in mind that the windows version behaves slightly different than the base getArgs
(because it uses actual windows API).