Directories
EPHS.Directories
— ModuleDirectories - the NonEmptyDtry
and Dtry
monads
A nonempty directory of T
s (NonEmptyDtry{T}
) is essentially a tree whose leaves hold values of type T
. Each value is addressed by the path from the root node to the respective leaf, given by a list of Symbol
s, see DtryPath
.
The monad unit sends a value of type T
to a tree consisting only of a leaf holding the value.
The monad multiplication flattens a directory of directories of T
s into a directory of T
s by grafting the trees stored at the leaves directly onto their respective parent nodes.
A (possibly empty) directory of T
s (Dtry{T}
) is either empty or it is a nonempty directory of T
s. The Dtry
monad is hence obtained by composing the NonEmptyDtry
monad with the 'Maybe monad'. The composition of the monads relies on a distributive law. Since subdirectories (subtrees) of a directory cannot be empty, the distributive law filters out any empty directories at the leaves, as they cannot be grafted onto their parent nodes.
This module implements directories as an immutable data structure. Subdirectories are stored in lexicographic order to ensure that two directories with the same set of paths (namespace) and the same associated values are equal.
The implementation supports simple access of subdirectories and values, pretty-printing, iteration, mapping, filtering, merging, etc.
EPHS.Directories.AbstractDtry
— TypeThe concrete subtypes of AbstractDtry
are NonEmptyDtry
and Dtry
.
EPHS.Directories.Dtry
— TypeA Dtry{T}
is either empty or it wraps a NonEmptyDtry
of T
s.
EPHS.Directories.Dtry
— MethodDtry(value::T) -> Dtry{T}
Construct a directory, which contains just a single value (monad unit).
EPHS.Directories.Dtry
— MethodDtry(pairs::Vararg{Pair{Symbol,Dtry{T}}}) -> Dtry{T}
Construct a directory of T
s from a number of pairs of names and subdirectories. Empty subdirectories are filtered out.
EPHS.Directories.Dtry
— MethodDtry{T}()
Construct an empty directory of T
s.
EPHS.Directories.DtryAccessError
— TypeAbstract supertype for exceptions that may be thrown when accessing directories. Concrete subtypes are DtryBranchError
(branch with a given name does not exist) and DtryLeafError
(given directory is not a leaf).
EPHS.Directories.DtryBranchError
— TypeDtryBranchError(dtry::AbstractDtry, name::Symbol)
The given directory has no direct subdirectory with the given name.
EPHS.Directories.DtryLeafError
— TypeDtryLeafError(dtry::AbstractDtry)
The given directory is not a leaf holding a value.
EPHS.Directories.DtryPath
— TypeA DtryPath
is a linked list of Symbol
s representing a path in a directory, see also ■
.
EPHS.Directories.DtryPath
— MethodDtryPath(names::Vararg{Symbol})
Construct a DtryPath
from a series of names.
Example
julia> DtryPath(:foo, :bar) == ■.foo.bar
true
EPHS.Directories.NonEmptyDtry
— TypeA NonEmptyDtry{T}
either contains a single value of type T
or it has at least one non-empty subdirectory of T
s.
EPHS.Directories.NonEmptyDtry
— MethodNonEmptyDtry(value::T) -> NonEmptyDtry{T}
Construct a non-empty directory, which contains just a single value (monad unit).
EPHS.Directories.NonEmptyDtry
— MethodNonEmptyDtry(pairs::Vararg{Pair{Symbol,NonEmptyDtry{T}}}) -> NonEmptyDtry{T}
Construct a non-empty directory of T
s from a number of pairs of names and non-empty subdirectories.
EPHS.Directories.■
— ConstantDtryPath
representing the root node of a directory. With that, ■.foo
represents the path to a subdirectory named foo
.
Base.:*
— Method*(p1::DtryPath, p2::DtryPath) -> DtryPath
Concatenate two DtryPath
s.
Example
julia> ■.foo * ■.bar == ■.foo.bar
true
Base.Iterators.zip
— Methodzip(dtry1::NonEmptyDtry{T1}, dtry2::NonEmptyDtry{T2}) -> NonEmptyDtry{Tuple{T1,T2}}
zip(dtry1::Dtry{T1}, dtry2::Dtry{T2}) -> Dtry{Tuple{T1,T2}}
Given a directory of T1
s and a directory of T2
s with the same tree sturcture, as well as a function f : T1 × T2 -> X
, produce a directory of Tuple{T1,T2}
s, where the value at path p
is given by (dtry1[p], dtry2[p])
.
Base.all
— Methodall(p, dtry::Dtry{T}) -> Bool
Returns true
if predicate p : T -> Bool
returns true
for all values of the directory.
Base.all
— Methodall(p, dtry::NonEmptyDtry{T}) -> Bool
Returns true
if predicate p : T -> Bool
returns true
for all values of the directory.
Base.collect
— Methodcollect(dtry::AbstractDtry{T}) -> Vector{T}
Collect values from a directory.
Base.filter
— Methodfilter(f, dtry::AbstractDtry{T}) -> Dtry{T}
Given a function f : T -> Bool
and a (nonempty) directory of T
s, produce a new directory of T
s by keeping the entry at path p
only if f(dtry[p]) == true
.
Base.foreach
— Methodforeach(f, dtry::Dtry{T}) -> Nothing
Call function f
on each Pair{DtryPath,T}
.
Base.foreach
— Methodforeach(f, dtry::NonEmptyDtry{T}) -> Nothing
Call function f
on each Pair{DtryPath,T}
.
Base.get
— Methodget(dtry::Dtry, path::DtryPath, default)
If path
refers to a value within dtry
, returns the value. Otherwise, returns default
.
Base.get
— Methodget(dtry::NonEmptyDtry, path::DtryPath, default)
If path
refers to a value within dtry
, returns the value. Otherwise, returns default
.
Base.getindex
— Methodgetindex(dtry::Dtry{T}, path::DtryPath) -> T
If path
refers to a value within dtry
, returns the value. Otherwise, throws a DtryAccessError
.
Base.getindex
— Methodgetindex(dtry::Dtry{T}) -> T
If dtry
isa leaf, dtry[]
returns its value. Otherwise, throws a DtryLeafError
Base.getindex
— Methodgetindex(dtry::NonEmptyDtry{T}) -> T
If dtry
isa leaf, dtry[]
returns its value. Otherwise, throws a DtryLeafError
Base.getindex
— Methodgetindex(dtry::NonEmptyDtry{T}, path::DtryPath) -> T
If path
refers to a value within dtry
, returns the value. Otherwise, throws a DtryAccessError
.
Base.isempty
— Methodisempty(dtry::AbstractDtry) -> Bool
Returns true
if the given directory is empty.
Base.length
— Methodlength(path::DtryPath) -> Int
Returns the length of the DtryPath
(linked list of Symbols
).
Example
julia> length(■.foo.bar) == 2
true
Base.length
— Methodlength(dtry::Dtry) -> Int
Returns the number of values (leaves) in the given directory.
Base.length
— Methodlength(dtry::NonEmptyDtry) -> Int
Returns the number of values (leaves) in the given directory.
Base.map
— Methodmap(f, dtry::NonEmptyDtry{T}) -> NonEmptyDtry{X}
map(f, dtry::Dtry{T}) -> Dtry{X}
Make a new directory of X
s with the same tree structure as dtry
, where the value at path p
is given by f(dtry[p])::X
. The return type X
of f
is inferred.
Base.map
— Methodmap(f, dtry::Dtry{T}, X::Type) -> Dtry{X}
Make a new directory of X
s with the same tree structure as dtry
, where the value at path p
is given by f(dtry[p])::X
.
Base.map
— Methodmap(f, dtry::NonEmptyDtry{T}, X::Type) -> NonEmptyDtry{X}
Make a new nonempty directory of X
s with the same tree structure as dtry
, where the value at path p
is given by f(dtry[p])::X
.
Base.mapreduce
— Methodmapreduce(f, op, dtry::Dtry{T}, default)
Transforms each value contained in the given directory using the function f : T -> X
and reduces the results using the binary operation op : X × X -> X
. For an empty directory, returns default
.
Base.mapreduce
— Methodmapreduce(f, op, dtry::NonEmptyDtry{T})
Transforms each value contained in the given directory using the function f : T -> X
and reduces the results using the binary operation op : X × X -> X
.
Base.merge
— Methodmerge(dtry1::NonEmptyDtry{T}, dtry2::NonEmptyDtry{T}) -> NonEmptyDtry{T}
merge(dtry1::Dtry{T}, dtry2::Dtry{T}) -> Dtry{T}
Merge two directories, given that their namespaces are disjoint, i.e. the union of their namespaces is prefix-free.
EPHS.Directories.filtermap
— Methodfiltermap(f, dtry::AbstractDtry{T}, X::Type) -> Dtry{X}
Make a new directory of X
s from a (nonempty) directory of T
s based on a function f : T -> Union{Some{X},Nothing}
. When f
returns nothing
, the respective entry is filtered out.
EPHS.Directories.foreachpath
— Methodforeachpath(f, dtry::Dtry) -> Nothing
Call function f
on each path::DtryPath
.
EPHS.Directories.foreachpath
— Methodforeachpath(f, dtry::NonEmptyDtry) -> Nothing
Call function f
on each path::DtryPath
.
EPHS.Directories.foreachvalue
— Methodforeachvalue(f, dtry::Dtry{T}) -> Nothing
Call function f
on each value::T
.
EPHS.Directories.foreachvalue
— Methodforeachvalue(f, dtry::NonEmptyDtry{T}) -> Nothing
Call function f
on each value::T
.
EPHS.Directories.haspath
— Methodhaspath(dtry::Dtry, path::DtryPath) -> Bool
Returns true
if the given directory contains a leaf/value at the given path.
EPHS.Directories.haspath
— Methodhaspath(dtry::NonEmptyDtry, path::DtryPath) -> Bool
Returns true
if the given directory contains a leaf/value at the given path.
EPHS.Directories.hasprefix
— Methodhasprefix(dtry::Dtry, prefix::DtryPath) -> Bool
Returns true
if the given directory has a (complete) path (to a leaf/value), which starts with the given prefix (or incomplete path).
EPHS.Directories.hasprefix
— Methodhasprefix(dtry::NonEmptyDtry, prefix::DtryPath) -> Bool
Returns true
if the given directory has a (complete) path (to a leaf/value), which starts with the given prefix (or incomplete path).
EPHS.Directories.mapwithpath
— Methodmapwithpath(f, dtry::Dtry{T}, X::Type) -> Dtry{X}
Make a new directory of X
s with the same tree structure as dtry
, where the value at path p
is given by f((p, dtry[p]))::X
.
EPHS.Directories.mapwithpath
— Methodmapwithpath(f, dtry::NonEmptyDtry{T}, X::Type) -> NonEmptyDtry{X}
Make a new directory of X
s with the same tree structure as dtry
, where the value at path p
is given by f((p, dtry[p]))::X
.
EPHS.Directories.zipmap
— Methodzipmap(f, dtry1::Dtry{T1}, dtry2::Dtry{T2}, X::Type) -> Dtry{X}
Given a directory of T1
s and a directory of T2
s with the same tree sturcture, as well as a function f : T1 × T2 -> X
, produce a new directory of X
s, where the value at path p
is given by f(dtry1[p], dtry2[p])
.
EPHS.Directories.zipmap
— Methodzipmap(f, dtry1::NonEmptyDtry{T1}, dtry2::NonEmptyDtry{T2}, X::Type) -> NonEmptyDtry{X}
Given a nonempty directory of T1
s and a nonempty directory of T2
s with the same tree sturcture, as well as a function f : T1 × T2 -> X
, produce a new nonempty directory of X
s, where the value at path p
is given by f(dtry1[p], dtry2[p])
.
EPHS.Directories.zipmapwithpath
— Methodzipmapwithpath(f, dtry1::Dtry{T1}, dtry2::Dtry{T2}, X::Type) -> Dtry{X}
Given a directory of T1
s and a directory of T2
s with the same tree sturcture, as well as a function f : DtryPath × T1 × T2 -> X
, produce a new directory of X
s, where the value at path p
is given by f(p, dtry1[p], dtry2[p])
.
EPHS.Directories.zipmapwithpath
— Methodzipmapwithpath(f, dtry1::NonEmptyDtry{T1}, dtry2::NonEmptyDtry{T2}, X::Type) -> NonEmptyDtry{X}
Given a directory of T1
s and a directory of T2
s with the same tree sturcture, as well as a function f : DtryPath × T1 × T2 -> X
, produce a new directory of X
s, where the value at path p
is given by f(p, dtry1[p], dtry2[p])
.
EPHS.MoreBase.flatten
— Methodflatten(dtry::NonEmptyDtry{NonEmptyDtry{T}}) -> Dtry{T}
Flattens a nonempty directory of nonempty directories (monad multiplication).
EPHS.MoreBase.flatten
— Methodflatten(dtry::Dtry{Dtry{T}}) -> Dtry{T}
Flattens a directory of directories (monad multiplication).