The join function is the conventional monad join operator. It is used to remove one level of monadic structure, projecting its bound argument into the outer level.
Parallel Join Patterns with Guards and Propagation
Join 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"
A JoinList - a list type with with cheap catenation.
Generally speaking, joinlists have cheap construction (cons, snoc and join aka. append) and expensive manipulation. For most use-cases Data.Sequence is a more appropriate data structure.
* 3.0 - Added views as per Data.Sequence and takes and drops. Changed show instance to mimic Data.Sequence.
* 2.0 - more operations and some bugfixes (toList...), wrap renamed to singleton.
Join path elements back together.
> Valid x => joinPath (splitPath x) == x
> joinPath  == ""
> Posix: joinPath ["test","file","path"] == "test/file/path"
This is a persistent data structure for disjoint sets.
The algorithm is described in "Introduction to Algorithms" by Cormen, et al. The implementation here uses both union by rank and path compression. We incur an O(logn) overhead because of the use of persistent maps.
Data.IntDisjointSet is as strict as possible.
Imperative ST/IO based disjoint set data structure.