Functional and persistent data structures for Julia. This is a work in progress and is currently not optimized for performance.
NOTE: The master
branch of FunctionalCollections
is for Julia v0.7 and up. For earlier Julia versions please use FunctionalCollections v0.3.x.
julia> Pkg.add("FunctionalCollections")
julia> using FunctionalCollections
Collection | Abbrev
----------------------------
PersistentVector | pvec
PersistentHashMap | phmap
PersistentArrayMap |
PersistentSet | pset
PersistentList | plist
PersistentQueue | pqueue
src/FunctionalCollections.jl contains all of the package's exports, though many built-ins are also implemented.
Persistent vectors are immutable, sequential, random-access data structures, with performance characteristics similar to arrays.
julia> v = @Persistent [1, 2, 3, 4, 5]
Persistent{Int64}[1, 2, 3, 4, 5]
Since persistent vectors are immutable, "changing" operations return a new vector instead of modifying the original.
julia> append(v, [6, 7])
Persistent{Int64}[1, 2, 3, 4, 5, 6, 7]
# v hasn't changed
julia> v
Persistent{Int64}[1, 2, 3, 4, 5]
Persistent vectors are random-access structures, and can be indexed into just like arrays.
julia> v[3]
3
But since they're immutable, it doesn't make sense to define index
assignment (v[3] = 42
) since assignment implies change. Instead,
assoc
returns a new persistent vector with some value associated
with a given index.
julia> assoc(v, 3, 42)
Persistent{Int64}[1, 2, 42, 4, 5]
Three functions, push
, peek
, and pop
, make up the persistent
vector stack interface. push
adds a single element (whereas append
adds all elements in the given collection, starting from the left),
peek
returns the last element of the vector, and pop
returns a new
vector without the last element.
julia> push(v, 6)
Persistent{Int64}[1, 2, 3, 4, 5, 6]
julia> peek(v)
5
julia> pop(v)
Persistent{Int64}[1, 2, 3, 4]
Persistent vectors also support iteration and higher-order sequence operations.
julia> for el in @Persistent ["foo", "bar", "baz"]
println(el)
end
foo
bar
baz
julia> map(x -> x * 2, v)
Persistent{Int64}[2, 4, 6, 8, 10]
julia> filter(iseven, v)
Persistent{Int64}[2, 4]
Persistent hash maps are immutable, unordered, associative structures,
similar to the built-in Dict
type.
julia> name = @Persistent Dict(:first => "Zach", :last => "Allaun")
Persistent{Symbol, String}[last => Allaun, first => Zach]
They can be queried in a manner similar to the dictionaries.
julia> name[:first]
"Zach"
julia> get(name,