Skip to content

Commit 6d09bc9

Browse files
Update path module documentation
1 parent 64dd83c commit 6d09bc9

4 files changed

Lines changed: 1072 additions & 969 deletions

File tree

core/src/Streamly/FileSystem/Path.hs

Lines changed: 62 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -5,81 +5,77 @@
55
-- Maintainer : streamly@composewell.com
66
-- Portability : GHC
77
--
8-
-- File system paths with flexible (gradual) typing, extensible,
8+
-- File system paths supporting flexible (gradual) typing; extensible,
99
-- high-performance, preserving the OS and filesystem encoding.
1010
--
11-
-- /Flexible/: you can choose the level of type safety you want. 'Path' is the
12-
-- basic path type which can represent a file, directory, absolute or relative
13-
-- path with no restrictions. Depending on how much type safety you want, you
14-
-- can choose appropriate type wrappers or a combination of those to wrap the
15-
-- 'Path' type.
11+
-- /Flexible typing/: you can choose the level of type safety you want. 'Path'
12+
-- is the basic path type which can represent a file, directory, absolute or
13+
-- relative path with no restrictions. Depending on how much type safety you
14+
-- want, you can choose appropriate type wrappers or a combination of those to
15+
-- wrap the 'Path' type in stricter types.
1616
--
1717
-- = Rooted Paths vs Branches
1818
--
19-
-- For the safety of the path append operation we make the distinction of
20-
-- rooted paths vs branches. A path that starts from some implicit or
21-
-- explicit root in the file system is a rooted path, for example, @\/usr\/bin@
22-
-- is a rooted path starting from an explicit file system root directory @/@.
23-
-- Similarly, @.\/bin@ is a path with an implicit root, this path is hanging
24-
-- from the current directory. A path that is not rooted is called a branch
25-
-- e.g. @local\/bin@ is a branch.
26-
--
27-
-- This distinction affords safety to the path append operation. We can always
28-
-- append a branch to a rooted path or to another branch. However, it does
29-
-- not make sense to append a rooted path to another rooted path. The default
19+
-- To ensure the safety of the append operation, we distinguish between
20+
-- rooted paths and branch-type paths. A path that starts from an explicit or
21+
-- implicit root in the file system is called a rooted path. For example,
22+
-- @\/usr\/bin@ is a rooted path starting from the explicit root directory @/@.
23+
-- Similarly, @.\/bin@ is rooted implicitly, hanging from the current directory.
24+
-- A path that is not rooted is called a branch; for example, @local\/bin@ is a
25+
-- branch.
26+
--
27+
-- This distinction ensures the safety of the path append operation. You can
28+
-- always append a branch to a rooted path or to another branch. However,
29+
-- it does not make sense to append one rooted path to another. The default
3030
-- append operation in the Path module checks for this and fails if the
31-
-- operation is incorrect. However, the programmer can force it by using the
32-
-- unsafe version of the append operation. You can also drop the root
33-
-- explicitly and use the safe append operation.
34-
--
35-
-- The "Streamly.FileSystem.Path.Seg" module provides explicit typing of path
36-
-- segments e.g. rooted paths vs branches. Rooted paths are represented by the
37-
-- @Rooted Path@ type and branches are represented by the @Branch Path@ type.
38-
-- If you use the 'Path' type then append can fail if you try to append a
39-
-- rooted path to another path, but if you use @Rooted Path@ and @Branch Path@
40-
-- types then append can never fail at run time as the types would not allow it
41-
-- at compile time.
42-
--
43-
-- = Absolute vs Relative Rooted Paths
44-
--
45-
-- Rooted paths can be absolute or relative. Absolute paths have an absolute
46-
-- root e.g. @\/usr\/bin@. Relative paths have a dynamic or relative root e.g.
47-
-- @.\/local\/bin@, or @.@, in these cases the root is current directory which
48-
-- is not absolute but can change dynamically. Note that there is no type level
49-
-- distinction for absolute and relative paths. The append operation requires a
50-
-- distinction between Rooted and Branch only.
51-
--
52-
-- = File vs Directory Paths
53-
--
54-
-- Independent of the rooted or branch distinction you can also make a type
55-
-- level distinction between file and directory type nodes using the
56-
-- "Streamly.FileSystem.Path.Node" module. @File Path@ type represents a file
57-
-- whereas @Dir Path@ represents a directory. This distinction provides safety
58-
-- against appending a path to a file. Append operation does not allow
59-
-- appending to 'File' types.
60-
--
61-
-- By default a path with a trailing separator is implicitly considered a
62-
-- directory path. However, the absence of a trailing separator does not convey
63-
-- any information, it could either be a directory or a file. Thus the append
64-
-- operation allows appending to even paths that do not have a trailing
65-
-- separator. However, when creating a typed path of 'File' type the conversion
66-
-- fails unless we explicitly drop the trailing separator.
31+
-- operation is invalid. However, the programmer can force it using the
32+
-- unsafe append operation. Alternatively, you can drop the root explicitly
33+
-- and use the safe append.
34+
--
35+
-- The "Streamly.FileSystem.Path.Seg" module provides explicit types for path
36+
-- segments, distinguishing rooted paths from branches. Rooted paths use the
37+
-- @Rooted Path@ type, and branches use the @Branch Path@ type. If you use the
38+
-- generic 'Path' type, append may fail at run time if you attempt to append
39+
-- a rooted path to another rooted path. In contrast, using the @Rooted Path@
40+
-- and @Branch Path@ types guarantees compile-time safety, preventing such errors.
41+
--
42+
-- Since we distinguish between rooted and branch-type paths, a separate
43+
-- distinction between absolute and relative paths is not required. Both are
44+
-- considered rooted paths, and all rooted paths are protected from invalid
45+
-- append operations. Only branch-type paths can be appended.
46+
--
47+
-- = File vs. Directory Paths
48+
--
49+
-- Independent of the rooted or branch distinction, you can also make a
50+
-- type-level distinction between file and directory nodes using the
51+
-- "Streamly.FileSystem.Path.Node" module. The type @File Path@ represents a
52+
-- file, whereas @Dir Path@ represents a directory. This distinction provides
53+
-- safety against appending to file type paths — append operations are not
54+
-- allowed on paths of type 'File'.
55+
--
56+
-- By default, a path with a trailing separator is implicitly considered a
57+
-- directory path. However, the absence of a trailing separator does not
58+
-- indicate whether the path is a file or a directory — it could be either.
59+
-- Therefore, when using the @Path@ type, the append operation allows appending
60+
-- to paths even if they lack a trailing separator. However, when creating a
61+
-- typed path of type 'File', the conversion fails unless the trailing
62+
-- separator is explicitly removed.
6763
--
6864
-- = Flexible Typing
6965
--
70-
-- You can use the 'Rooted', 'Branch' or 'Dir', 'File' types independent of
71-
-- each other by using only the required module. If you want both types of
72-
-- distinctions then you can use them together as well using the
73-
-- "Streamly.FileSystem.Path.SegNode" module. For example, the @Rooted (Dir
74-
-- Path)@ represents a rooted path which is a directory. You can only append to
75-
-- a path that has 'Dir' in it and you can only append a 'Branch' type.
76-
--
77-
-- You can choose to use just the basic 'Path' type or any combination of safer
78-
-- types. You can upgrade or downgrade the safety by converting types using the
79-
-- @adapt@ operation. Whenever a less restrictive path type is converted to a
80-
-- more restrictive path type, the conversion involves run-time checks and it
81-
-- may fail. However, a more restrictive path type can be freely converted to a
82-
-- less restrictive one.
66+
-- You can use the 'Rooted', 'Branch', 'Dir', and 'File' types independently by
67+
-- importing only the required modules. If you want both types of distinctions,
68+
-- you can use them together via the "Streamly.FileSystem.Path.SegNode" module.
69+
-- For example, @Rooted (Dir Path)@ represents a rooted path that is a
70+
-- directory. You can append other paths only to paths that have a 'Dir' type,
71+
-- and only a path of type 'Branch' can be appended.
72+
--
73+
-- You may choose to use the basic 'Path' type or any combination of the safer
74+
-- types. You can upgrade or downgrade the safety level by converting between
75+
-- types using the @adapt@ operation. When converting from a less restrictive
76+
-- type to a more restrictive one, run-time checks are performed, and the
77+
-- conversion may fail. However, converting from a more restrictive type to a
78+
-- less restrictive one is always allowed.
8379
--
8480
-- = Extensibility
8581
--

0 commit comments

Comments
 (0)