Agenda.Interest (Agenda v0.1.0)

Copy Markdown View Source

One resource would like a session with another.

Everything else in this library is supply: what exists, when it is free, and what may not collide. An interest is the other half — demand — and it is what turns a pile of resources into a programme without anybody writing the sessions by hand.

The motivating case is a hosted-buyer programme, where buyers and suppliers register interest in each other and the organiser holds a meeting wherever the interest is returned. Interest that is not returned is not a meeting, which is why mutual/1 is the function that matters and one_sided/1 is reported separately rather than quietly scheduled.

An interest is deliberately not a session. It says two parties would like to meet, and says nothing about when, for how long, or where — those belong to the session it becomes, and one set of interests can be turned into meetings of different lengths for different days without being restated.

Summary

Types

Two resources that named each other.

t()

A resource's stated interest in meeting another.

Functions

The pairs who named each other.

Build an interest.

The interests that were never returned.

Types

pair()

@type pair() :: {String.t(), String.t()}

Two resources that named each other.

t()

@type t() :: %Agenda.Interest{from: String.t(), to: String.t()}

A resource's stated interest in meeting another.

Functions

mutual(interests)

@spec mutual([t()]) :: [pair()]

The pairs who named each other.

Each pair is returned once, in a stable order, so the same set of interests always produces the same meetings regardless of the order they were registered in.

Arguments

  • interests is a list of t/0.

Returns

  • A list of {first, second} name pairs, sorted.

Examples

iex> {:ok, asked} = Agenda.Interest.new("Kim", "Harbour Tours")
iex> {:ok, agreed} = Agenda.Interest.new("Harbour Tours", "Kim")
iex> Agenda.Interest.mutual([asked, agreed])
[{"Harbour Tours", "Kim"}]

iex> {:ok, asked} = Agenda.Interest.new("Kim", "Harbour Tours")
iex> Agenda.Interest.mutual([asked])
[]

new(from, to)

@spec new(Agenda.Resource.t() | String.t(), Agenda.Resource.t() | String.t()) ::
  {:ok, t()} | {:error, :self_interest}

Build an interest.

Arguments

  • from is the resource registering the interest, as a Agenda.Resource.t/0 or its name.

  • to is the resource it would like to meet, in the same two forms.

Returns

  • {:ok, interest}; or

  • {:error, :self_interest} when a resource names itself, which no meeting can satisfy.

Examples

iex> {:ok, interest} = Agenda.Interest.new("Kim", "Harbour Tours")
iex> {interest.from, interest.to}
{"Kim", "Harbour Tours"}

iex> Agenda.Interest.new("Kim", "Kim")
{:error, :self_interest}

one_sided(interests)

@spec one_sided([t()]) :: [t()]

The interests that were never returned.

Reported rather than scheduled: a meeting only one party asked for is a decision for the organiser, not something to book on their behalf.

Arguments

  • interests is a list of t/0.

Returns

  • A list of t/0, in the order they were registered.

Examples

iex> {:ok, asked} = Agenda.Interest.new("Kim", "Harbour Tours")
iex> {:ok, agreed} = Agenda.Interest.new("Harbour Tours", "Kim")
iex> {:ok, hopeful} = Agenda.Interest.new("Sam", "Harbour Tours")
iex> Agenda.Interest.one_sided([asked, agreed, hopeful]) |> Enum.map(& &1.from)
["Sam"]