import torch
from typing import Callable
from typing import Iterable
from typing import Tuple


def make_batcher(
    x: torch.Tensor, y: torch.Tensor, batch_size: int
) -> Callable[[], Iterable[Tuple[torch.Tensor, torch.Tensor]]]:
    """Returns a function that can be called to yield batches over x and y."""
    assert x.shape[0] == y.shape[0]

    idxes = range(0, x.shape[0], batch_size)

    def batcher() -> Iterable[Tuple[torch.Tensor, torch.Tensor]]:
        for start in idxes:
            end = start + batch_size
            yield x[start:end], y[start:end]

    return batcher