# `ShotDs.Data.TypeScheme`
[🔗](https://github.com/jcschuster/ShotDs/blob/v1.1.1/lib/shot_ds/data/type_scheme.ex#L1)

Represents a rank-1 polymorphic type scheme:

$$\forall \alpha_1\dots\alpha_n.\, \tau$$

The quantified variables in `vars` are type variable references which appear
inside the body type and are universally quantified at the outermost level
(prenex form).

At each use site, schemes are *instantiated* into fresh monotypes via
`instantiate/1`, which replaces every quantified variable with a fresh
reference. This is the mechanism that allows polymorphic constants like
$=^\alpha$ (with scheme $\forall\alpha.\,\alpha\to\alpha\to o$) to be used at
different types within the same formula.

Monotypes can be lifted into trivial schemes (with empty `vars`) using
`mono/1`.

## Example

    iex> alpha = make_ref()
    iex> scheme = TypeScheme.new([alpha], Type.new(alpha, alpha))
    iex> match?(%TypeScheme{vars: [^alpha]}, scheme)
    true

# `t`

```elixir
@type t() :: %ShotDs.Data.TypeScheme{
  body: ShotDs.Data.Type.t(),
  vars: [ShotDs.Data.Type.variable_id()]
}
```

Elixir type of a (rank-1 polymorphic) type scheme.

# `free_type_vars`

```elixir
@spec free_type_vars(t()) :: MapSet.t(ShotDs.Data.Type.variable_id())
```

Returns the set of free type variables in the scheme. This is defined as the
set of free type variables in the body without the bound type variables.

# `generalize`

```elixir
@spec generalize(ShotDs.Data.Type.t(), MapSet.t(ShotDs.Data.Type.variable_id())) ::
  t()
```

Generalizes a given type by binding free type variables in a scheme.

# `instantiate`

```elixir
@spec instantiate(t()) :: ShotDs.Data.Type.t()
```

Instantiates the bound type variables in the given type scheme with fresh type
variables.

# `mono`

```elixir
@spec mono(ShotDs.Data.Type.t()) :: t()
```

Constructs a trivial type scheme representing the given monotype.

# `new`

```elixir
@spec new([ShotDs.Data.Type.variable_id()], ShotDs.Data.Type.t()) :: t()
```

Constructs a type scheme binding the type variables `vars` in the (possibly
polymorphic) type `body`.

---

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