defmodule Algae.Tree.Rose do
@moduledoc """
A tree with any number of nodes at each level
## Examples
%Algae.Tree.Rose{
rose: 42,
forest: [
%Algae.Tree.Rose{
rose: "hi"
},
%Algae.Tree.Rose{
forest: [
%Algae.Tree.Rose{
rose: 0.4
}
]
},
%Algae.Tree.Rose{
rose: "there"
}
]
}
"""
alias __MODULE__
import Algae
@type rose :: any()
@type forest :: [t()]
@doc """
Create a simple `Algae.Rose` tree, with an empty forest and one rose.
## Examples
iex> new(42)
%Algae.Tree.Rose{
rose: 42,
forest: []
}
"""
defdata do
rose :: any()
forest :: [t()]
end
@doc """
Create an `Algae.Rose` tree, passing a forest and a rose.
## Examples
iex> new(42, [new(55), new(14)])
%Algae.Tree.Rose{
rose: 42,
forest: [
%Algae.Tree.Rose{rose: 55},
%Algae.Tree.Rose{rose: 14}
]
}
"""
@spec new(rose(), forest()) :: t()
def new(rose, forest), do: %Rose{rose: rose, forest: forest}
@doc """
Wrap another tree around an existing one, relegating it to the forest.
## Examples
iex> 55
...> |> new()
...> |> layer(42)
...> |> layer(99)
...> |> layer(6)
%Algae.Tree.Rose{
rose: 6,
forest: [
%Algae.Tree.Rose{
rose: 99,
forest: [
%Algae.Tree.Rose{
rose: 42,
forest: [
%Algae.Tree.Rose{
rose: 55
}
]
}
]
}
]
}
"""
@spec layer(t(), rose()) :: t()
def layer(tree, rose), do: %Rose{rose: rose, forest: [tree]}
end