# `Localize.Inflection.ConceptList`
[🔗](https://github.com/elixir-localize/localize/blob/v1.4.0/lib/localize/inflection/concept_list.ex#L1)

An and/or list of concepts rendered with locale-correct
conjunctions.

This is the port of the upstream `SemanticConceptList` and the
`createAndList`/`createOrList` factories. Separators derive from
Localize's own CLDR list patterns, and language-specific
conjunction rules are applied on top: Spanish *y* becomes *e*
before an i-sound (with the diphthong exception), Italian *e*
becomes *ed* before a vowel, Hebrew prefixes ו directly to
Hebrew words but hyphenates Latin ones, and the Korean particle
과/와 follows the sound of the preceding word.

Constraints put on the list propagate to every member, so an
and-list of nouns can be pluralized or case-marked as a unit.
Lists nest: a `ConceptList` can be a member of another
`ConceptList`.

# `t`

```elixir
@type t() :: %Localize.Inflection.ConceptList{
  after_first: term(),
  after_last: term(),
  avoid_affix_redundancy: term(),
  before_first: term(),
  before_last: term(),
  concepts: term(),
  conjunction: term(),
  conjunction_kind: term(),
  item_delimiter: term(),
  item_prefix: term(),
  item_suffix: term(),
  locale: term()
}
```

# `and_list`

Builds an and-list of concepts.

### Arguments

* `locale` is a locale atom or string, canonically BCP47.

* `concepts` is a list of `Localize.Inflection.Concept` or
  nested `Localize.Inflection.ConceptList` members; nil members
  are dropped.

### Returns

* `{:ok, list}` or `{:error, exception}` when the locale's list
  patterns are unavailable.

### Examples

    iex> {:ok, jane} = Localize.Inflection.Concept.new(:es, "Jane")
    iex> {:ok, ivan} = Localize.Inflection.Concept.new(:es, "Ivan")
    iex> {:ok, list} = Localize.Inflection.ConceptList.and_list(:es, [jane, ivan])
    iex> Localize.Inflection.ConceptList.to_speakable_string(list)
    "Jane e Ivan"

    iex> concepts =
    ...>   for word <- ["gato", "gata"] do
    ...>     {:ok, concept} = Localize.Inflection.Concept.new(:es, word)
    ...>     concept
    ...>   end
    iex> {:ok, list} = Localize.Inflection.ConceptList.and_list(:es, concepts)
    iex> {:ok, list} = Localize.Inflection.ConceptList.put_constraint(list, :number, :plural)
    iex> Localize.Inflection.ConceptList.to_speakable_string(list)
    "gatos y gatas"

# `exists?`

Returns true when the list has at least one member.

### Arguments

* `list` is a concept list.

### Returns

* `true` when the list has a member, and `false` when it is empty
  or is not a concept list.

### Examples

    iex> {:ok, list} = Localize.Inflection.ConceptList.and_list(:es, [])
    iex> Localize.Inflection.ConceptList.exists?(list)
    false

# `feature_value`

Returns the value of a feature for the list.

A grammatical category (number, gender, case, ...) returns the
first member's value; a display feature renders the whole list
with each member replaced by its feature value.

### Arguments

* `list` is a concept list.

* `name` is the feature, such as `:number`.

### Returns

* The feature's value, or `nil` when the list is empty or is not a
  concept list.

### Examples

    iex> concepts =
    ...>   for word <- ["Jane", "Omar"] do
    ...>     {:ok, concept} = Localize.Inflection.Concept.new(:es, word)
    ...>     concept
    ...>   end
    iex> {:ok, list} = Localize.Inflection.ConceptList.and_list(:es, concepts)
    iex> Localize.Inflection.ConceptList.feature_value(list, :number)
    :singular

# `or_list`

Builds an or-list of concepts.

### Arguments

* `locale` is a locale atom or string, canonically BCP47.

* `concepts` is a list of `Localize.Inflection.Concept` or
  nested `Localize.Inflection.ConceptList` members; nil members
  are dropped.

### Returns

* `{:ok, list}` or `{:error, exception}` when the locale's list
  patterns are unavailable.

### Examples

    iex> concepts =
    ...>   for word <- ["Jane", "Omar"] do
    ...>     {:ok, concept} = Localize.Inflection.Concept.new(:es, word)
    ...>     concept
    ...>   end
    iex> {:ok, list} = Localize.Inflection.ConceptList.or_list(:es, concepts)
    iex> Localize.Inflection.ConceptList.to_speakable_string(list)
    "Jane u Omar"

# `plain_list`

Builds a plain list of concepts, with no conjunction and no
separators, as the upstream `SemanticConceptList` constructor
does. Separators are then set with `put_separator/3`.

### Arguments

* `locale` is a locale atom or string, canonically BCP47.

* `concepts` is a list of `Localize.Inflection.Concept` or
  nested `Localize.Inflection.ConceptList` members; nil members
  are dropped.

### Returns

* `{:ok, list}` or `{:error, exception}` when a member is not a
  concept.

### Examples

    iex> concepts =
    ...>   for word <- ["gatos", "idiomas"] do
    ...>     {:ok, concept} = Localize.Inflection.Concept.new(:es, word)
    ...>     concept
    ...>   end
    iex> {:ok, list} = Localize.Inflection.ConceptList.plain_list(:es, concepts)
    iex> Localize.Inflection.ConceptList.to_speakable_string(list)
    "gatosidiomas"

# `put_avoid_affix_redundancy`

Sets whether an item that already starts with the item prefix,
or ends with the item suffix, is left without another.

### Arguments

* `list` is a concept list.

* `avoid?` is `true`, the default for every list, or `false`.

### Returns

* The updated list, or `{:error, exception}` when `list` is not a
  concept list or `avoid?` is not a boolean.

### Examples

    iex> concepts =
    ...>   for word <- ["[gato]", "gata"] do
    ...>     {:ok, concept} = Localize.Inflection.Concept.new(:es, word)
    ...>     concept
    ...>   end
    iex> {:ok, list} = Localize.Inflection.ConceptList.plain_list(:es, concepts)
    iex> list =
    ...>   list
    ...>   |> Localize.Inflection.ConceptList.put_separator(:item_prefix, "[")
    ...>   |> Localize.Inflection.ConceptList.put_separator(:item_suffix, "]")
    iex> Localize.Inflection.ConceptList.to_speakable_string(list)
    "[gato][gata]"
    iex> list
    ...> |> Localize.Inflection.ConceptList.put_avoid_affix_redundancy(false)
    ...> |> Localize.Inflection.ConceptList.to_speakable_string()
    "[[gato]][gata]"

# `put_constraint`

Puts a constraint on every member and records it on the list.

### Arguments

* `list` is a concept list.

* `name` is a grammatical feature, such as `:number` or `:gender`.

* `value` is the feature's value, such as `:plural`.

### Returns

* `{:ok, list}` with every member constrained, or

* `{:error, exception}` when a member cannot take the constraint or
  `list` is not a concept list.

### Examples

    iex> concepts =
    ...>   for word <- ["Jane", "Omar"] do
    ...>     {:ok, concept} = Localize.Inflection.Concept.new(:es, word)
    ...>     concept
    ...>   end
    iex> {:ok, list} = Localize.Inflection.ConceptList.and_list(:es, concepts)
    iex> {:ok, list} = Localize.Inflection.ConceptList.put_constraint(list, :number, :plural)
    iex> Localize.Inflection.ConceptList.to_speakable_string(list)
    "Janes y Omares"

# `put_separator`

Sets a separator field.

### Arguments

* `list` is a concept list.

* `field` is one of `:before_first`, `:after_first`,
  `:item_delimiter`, `:before_last`, `:after_last`,
  `:item_prefix` or `:item_suffix`.

* `value` is the separator as a speakable string; the empty
  string unsets the field, re-enabling any language-specific
  dynamic conjunction.

### Returns

* The concept list with the field set, or

* `{:error, exception}` when `field` is not a separator field or
  `list` is not a concept list.

### Examples

    iex> concepts =
    ...>   for word <- ["Jane", "Omar"] do
    ...>     {:ok, concept} = Localize.Inflection.Concept.new(:es, word)
    ...>     concept
    ...>   end
    iex> {:ok, list} = Localize.Inflection.ConceptList.plain_list(:es, concepts)
    iex> list = Localize.Inflection.ConceptList.put_separator(list, :item_delimiter, " / ")
    iex> Localize.Inflection.ConceptList.to_speakable_string(list)
    "Jane / Omar"

# `size`

Returns the number of members.

### Arguments

* `list` is a concept list.

### Returns

* The number of members, or

* `{:error, exception}` when `list` is not a concept list.

### Examples

    iex> concepts =
    ...>   for word <- ["Jane", "Omar"] do
    ...>     {:ok, concept} = Localize.Inflection.Concept.new(:es, word)
    ...>     concept
    ...>   end
    iex> {:ok, list} = Localize.Inflection.ConceptList.and_list(:es, concepts)
    iex> Localize.Inflection.ConceptList.size(list)
    2

# `to_speakable_string`

Renders the list with locale-correct separators.

### Arguments

* `list` is a concept list.

### Returns

* A speakable string, or `nil` when the list is empty, or

* `{:error, exception}` when `list` is not a concept list.

### Examples

    iex> concepts =
    ...>   for word <- ["Jane", "Omar"] do
    ...>     {:ok, concept} = Localize.Inflection.Concept.new(:es, word)
    ...>     concept
    ...>   end
    iex> {:ok, list} = Localize.Inflection.ConceptList.and_list(:es, concepts)
    iex> Localize.Inflection.ConceptList.to_speakable_string(list)
    "Jane y Omar"

---

*Consult [api-reference.md](api-reference.md) for complete listing*
