exercism/elixir/simple-linked-list/linked_list.exs

104 lines
1.7 KiB
Elixir

defmodule LinkedList do
@opaque t :: tuple()
@doc """
Construct a new LinkedList
"""
@spec new() :: t
def new() do
[]
end
@doc """
Push an item onto a LinkedList
"""
@spec push(t, any()) :: t
def push(list, elem) do
[elem | list]
end
@doc """
Calculate the length of a LinkedList
"""
@spec length(t) :: non_neg_integer()
def length(list) do
Enum.count(list)
end
@doc """
Determine if a LinkedList is empty
"""
@spec empty?(t) :: boolean()
def empty?(list) do
Enum.empty?(list)
end
@doc """
Get the value of a head of the LinkedList
"""
@spec peek(t) :: {:ok, any()} | {:error, :empty_list}
def peek(list) do
cond do
empty?(list) ->
{:error, :empty_list}
true ->
{:ok, hd(list)}
end
end
@doc """
Get tail of a LinkedList
"""
@spec tail(t) :: {:ok, t} | {:error, :empty_list}
def tail(list) do
cond do
empty?(list) ->
{:error, :empty_list}
true ->
{:ok, tl(list)}
end
end
@doc """
Remove the head from a LinkedList
"""
@spec pop(t) :: {:ok, any(), t} | {:error, :empty_list}
def pop(list) do
cond do
empty?(list) ->
{:error, :empty_list}
true ->
[hd | tail] = list
{:ok, hd, tail}
end
end
@doc """
Construct a LinkedList from a stdlib List
"""
@spec from_list(list()) :: t
def from_list(list) do
list
end
@doc """
Construct a stdlib List LinkedList from a LinkedList
"""
@spec to_list(t) :: list()
def to_list(list) do
Enum.to_list(list)
end
@doc """
Reverse a LinkedList
"""
@spec reverse(t) :: t
def reverse(list) do
# Your implementation here...
Enum.reverse(list)
end
end