containers v0.7.0 Containers View Source

Containers are functional data structures that help provide greater runtime safety and polymorphism.

Protocols

  • Appendable - A container that provies an interface of append. Safe against nil values. Namely when passing a container with the value nil into either the first of second argument to append, the other value is not change and there is no runtime error.
  • Mappable - A container that provies an interface to map. When map is called on a container that has a nil 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 of and_then. This allows the chaining of computations.
  • Unwrappable - A container that provides an interface to safe and unsafe unwrapping of inner value. Safe will need a default in case of nil value of container, helping prevent runtime errors. Unsafe will just return the value of the container regardless of a nil value potentially causing runtime errors
  • Joinable - A container that provides an interface to join 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

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 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}
Link to this function map2(s, f) View Source
map2(mappable, (... -> any)) :: mappable

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.

Link to this function mapn(mappable, n, f) View Source
mapn(mappable, integer, (... -> any)) :: mappable

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.

Link to this function safe_unwrap(s, default) View Source
safe_unwrap(unwrappable, any) :: any

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"
Link to this function unsafe_unwrap(s) View Source
unsafe_unwrap(unwrappable) :: any

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