# `GEPA.DataLoader`
[🔗](https://github.com/nshkrdotcom/gepa_ex/blob/v0.3.0/lib/gepa/data_loader.ex#L36)

Protocol-style data access abstraction.

The official Python implementation normalizes in-memory lists into a
`DataLoader`. The Elixir port keeps the same seam while allowing custom
loader structs to provide stable IDs and ordered fetches.

# `data_id`

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

# `data_inst`

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

# `t`

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

# `all_ids`

```elixir
@callback all_ids(t()) :: [data_id()]
```

# `fetch`

```elixir
@callback fetch(t(), [data_id()]) :: [data_inst()]
```

# `size`

```elixir
@callback size(t()) :: non_neg_integer()
```

# `all_ids`

```elixir
@spec all_ids(t()) :: [data_id()]
```

# `ensure`

```elixir
@spec ensure([data_inst()] | t() | nil) :: t() | nil
```

Normalize raw lists into `GEPA.DataLoader.List`; pass loader structs through.

# `fetch`

```elixir
@spec fetch(t(), [data_id()]) :: [data_inst()]
```

# `size`

```elixir
@spec size(t()) :: non_neg_integer()
```

---

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