# `Comp`
[🔗](https://github.com/ash-project/ash/blob/v3.23.1/lib/comparable/comp.ex#L6)

Provides utilities to implement and work with `Comparable` types

# `left`

```elixir
@type left() :: term()
```

# `right`

```elixir
@type right() :: term()
```

# `compare`

```elixir
@spec compare(left(), right()) :: Comparable.ord()
```

Compare left and right term

## Examples

    iex> Comp.compare(1, 2)
    :lt
    iex> Comp.compare(2, 1)
    :gt
    iex> Comp.compare(1, 1)
    :eq

# `defcomparable`
*macro* 

Helper to define ordering relation for pair of types,
accepts two `term :: type` pairs
and block of code where relation is described.

## Examples

    iex> quote do
    ...>   use Comp
    ...>   defmodule Foo do
    ...>     defstruct [:value, :meta]
    ...>   end
    ...>   defmodule Bar do
    ...>     defstruct [:value, :meta]
    ...>   end
    ...>   defcomparable %Foo{value: left} :: Foo, %Foo{value: right} :: Foo do
    ...>     Comp.compare(left, right)
    ...>   end
    ...>   defcomparable %Foo{value: left} :: Foo, %Bar{value: right} :: Bar do
    ...>     Comp.compare(left, right)
    ...>   end
    ...>   defcomparable %Foo{value: left} :: Foo, right :: Integer do
    ...>     Comp.compare(left, right)
    ...>   end
    ...> end
    ...> |> Code.compile_quoted
    iex> quote do
    ...>   x = %Foo{value: 1, meta: 1}
    ...>   y = %Foo{value: 1, meta: 2}
    ...>   Comp.equal?(x, y) && Comp.equal?(y, x)
    ...> end
    ...> |> Code.eval_quoted
    ...> |> elem(0)
    true
    iex> quote do
    ...>   x = %Foo{value: 1, meta: 1}
    ...>   y = %Bar{value: 1, meta: 2}
    ...>   Comp.equal?(x, y) && Comp.equal?(y, x)
    ...> end
    ...> |> Code.eval_quoted
    ...> |> elem(0)
    true
    iex> quote do
    ...>   x = %Foo{value: 1, meta: 1}
    ...>   y = 1
    ...>   Comp.equal?(x, y) && Comp.equal?(y, x)
    ...> end
    ...> |> Code.eval_quoted
    ...> |> elem(0)
    true

# `eq`
*macro* 

# `equal?`

```elixir
@spec equal?(left(), right()) :: boolean()
```

Is left term equal to right term?

## Examples

    iex> Comp.equal?(1, 1)
    true
    iex> Comp.equal?(1, :hello)
    false

# `greater_or_equal?`

```elixir
@spec greater_or_equal?(left(), right()) :: boolean()
```

Is left term greater or equal to right term?

## Examples

    iex> Comp.greater_or_equal?(1, 1)
    true
    iex> Comp.greater_or_equal?(1, 2)
    false
    iex> Comp.greater_or_equal?(2, 1)
    true

# `greater_than?`

```elixir
@spec greater_than?(left(), right()) :: boolean()
```

Is left term greater than right term?

## Examples

    iex> Comp.greater_than?(1, 1)
    false
    iex> Comp.greater_than?(1, 2)
    false
    iex> Comp.greater_than?(2, 1)
    true

# `gt`
*macro* 

# `less_or_equal?`

```elixir
@spec less_or_equal?(left(), right()) :: boolean()
```

Is left term less or equal to right term?

## Examples

    iex> Comp.less_or_equal?(1, 1)
    true
    iex> Comp.less_or_equal?(1, 2)
    true
    iex> Comp.less_or_equal?(2, 1)
    false

# `less_than?`

```elixir
@spec less_than?(left(), right()) :: boolean()
```

Is left term less than right term?

## Examples

    iex> Comp.less_than?(1, 1)
    false
    iex> Comp.less_than?(1, 2)
    true
    iex> Comp.less_than?(2, 1)
    false

# `lt`
*macro* 

# `max`

```elixir
@spec max(left(), right()) :: left() | right()
```

Returns the biggest of the two given terms, if terms are equal - then the first one is returned

## Examples

    iex> Comp.max(1, 1)
    1
    iex> Comp.max(1, 2)
    2
    iex> Comp.max(2, 1)
    2

# `min`

```elixir
@spec min(left(), right()) :: left() | right()
```

Returns the smallest of the two given terms, if terms are equal - then the first one is returned

## Examples

    iex> Comp.min(1, 1)
    1
    iex> Comp.min(1, 2)
    1
    iex> Comp.min(2, 1)
    1

# `not_equal?`

```elixir
@spec not_equal?(left(), right()) :: boolean()
```

Is left term not equal to right term?

## Examples

    iex> Comp.not_equal?(1, 1)
    false
    iex> Comp.not_equal?(1, :hello)
    true

# `type_of`

---

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