containers v0.7.1 Containers View Source
Containers are functional data structures that help provide greater runtime safety and polymorphism.
Protocols
Appendable
- A container that provies an interface ofappend
. Safe againstnil
values. Namely when passing a container with the valuenil
into either the first of second argument toappend
, the other value is not change and there is no runtime error.Mappable
- A container that provies an interface tomap
. Whenmap
is called on a container that has anil
value that container just passes through with out the mapping function being called, and this helps prevent runtime errors.Sequenceable
- A container that provides an interface ofand_then
. This allows the chaining of computations.Unwrappable
- A container that provides an interface tosafe
andunsafe
unwrapping of inner value. Safe will need a default in case ofnil
value of container, helping prevent runtime errors. Unsafe will just return the value of the container regardless of anil
value potentially causing runtime errorsJoinable
- A container that provides an interface tojoin
function. This allows for nested containers of the same container type to have the outter layer removed.
Since these are protocols, and highly decoupled, a developer can implement them as needed on their own structs.
Link to this section Summary
Functions
>>>
is the infix operator for and_then
and_then is a function that will allow chaining of computations while passing the value
of the
last computation
Append two values of the Containers.Appendable protocol
concat a list of Containers that implement the Appendable protocol
This is useful for when you have a container that inner structure of that same container, and you want to join that down to one level
map some function f
of the some structure s
. Works like the Enum.map
but provides
more polymorphic protocol, and does rely on the Enumerable
protocol allowing use of
just getting map without needing to implement the full Enumerable
protocol
map some function f
over some nested strcutre s
. This is useful for when you have a
mappable in another mappable and you just want to use a mapping function on the inner
value of the nested map
Map some mapping function f
on the innner value n
number of mappable container structures deep. This is
useful for when you have deeply nested containers that are mappable and you want to operator
on the most inner value without have to unwrap
safely unwrap the inner value of a container, proviing a default in case the value is nil
.
This is should help prevent runtime errors within a |>
chain handling strings
unsafely unwrap the inner value of a continer. This may return nil so any guarantees against a runtime error no longer apply
Link to this section Types
appendable() :: Containers.Text.t | Containers.Optional.t
mappable :: Containers.Text.t | Containers.Optional.t | Containers.Result.t | list
Link to this section Functions
>>>
is the infix operator for and_then
Examples
iex> import Containers
iex> my_optional = Containers.Optional.to_optional(1)
iex> my_optional >>> fn(i) -> Containers.Optional.to_optional(i + 1) end
%Containers.Optional{value: 2}
and_then(sequenceable, (any -> sequenceable)) :: sequenceable
and_then is a function that will allow chaining of computations while passing the value
of the
last computation.
Append two values of the Containers.Appendable protocol
This is useful for chaning of appending appendable items safely. That is to say if there
is a nil
value being used like nil <> " world!"
there will be a run time error. In this
case the container for the string type will safe do concatenation.
Examples
iex> hello = Containers.Text.from_string("Hello")
iex> world = Containers.Text.from_string(" world!")
iex> Containers.append(hello, world)
%Containers.Text{value: "Hello world!"}
iex> hello = Containers.Text.from_string("Hello")
iex> world = Containers.Text.from_string(" world!")
iex> nil_string = Containers.Text.from_string(nil)
iex> hello |> Containers.append(nil_string) |> Containers.append(world)
%Containers.Text{value: "Hello world!"}
concat a list of Containers that implement the Appendable protocol
hello_world = "hello_world"
hello_world |> String.split("_")
|> Enum.map(&String.capitalize/1)
|> Enum.map(&Containers.Text.from_string/1)
|> Containers.concat()
|> Containers.safe_unwrap("")
"HelloWorld"
Examples
iex> hello = Containers.Text.from_string("hello")
iex> world = Containers.Text.from_string(" world")
iex> excliam = Containers.Text.from_string("!")
iex> Containers.concat([hello, world, excliam])
%Containers.Text{value: "hello world!"}
This is useful for when you have a container that inner structure of that same container, and you want to join that down to one level.
Examples
iex> nested = %Containers.Optional{value: %Containers.Optional{value: "hello"}}
iex> Containers.join(nested)
%Containers.Optional{value: "hello"}
map some function f
of the some structure s
. Works like the Enum.map
but provides
more polymorphic protocol, and does rely on the Enumerable
protocol allowing use of
just getting map without needing to implement the full Enumerable
protocol.
Examples
iex> my_optional = Containers.Optional.to_optional(1)
iex> Containers.map(my_optional, fn(i) -> i + 1 end)
%Containers.Optional{value: 2}
map some function f
over some nested strcutre s
. This is useful for when you have a
mappable in another mappable and you just want to use a mapping function on the inner
value of the nested map.
Map some mapping function f
on the innner value n
number of mappable container structures deep. This is
useful for when you have deeply nested containers that are mappable and you want to operator
on the most inner value without have to unwrap.
Note there is a provided map2
function in this module for mapping two layers deeps, but if you needing
mapping for a strucuture that is more deeply nested then 2 contianers, then this is the function
you are looking for.
safely unwrap the inner value of a container, proviing a default in case the value is nil
.
This is should help prevent runtime errors within a |>
chain handling strings.
Examples
iex> my_string = Containers.Text.from_string("hello")
iex> Containers.safe_unwrap(my_string, "this wont be needed")
"hello"
iex> my_nil_string = Containers.Text.from_string(nil)
iex> Containers.safe_unwrap(my_nil_string, "This will be the value")
"This will be the value"
unsafely unwrap the inner value of a continer. This may return nil so any guarantees against a runtime error no longer apply.
Examples
iex> my_string = Containers.Text.from_string("Hello")
iex> Containers.unsafe_unwrap(my_string)
"Hello"
iex> my_nil_string = Containers.Text.from_string(nil)
iex> Containers.unsafe_unwrap(my_nil_string)
nil