Прошлый пост был о том, как пользоваться составным типом данных — точкой на плоскости. Теперь о том, как этот тип реализовать. Сделать это можно при помощи пар.

Пара — это структура данных, которая объединяет в себе два значения. В джаваскрипте пар по дефолту нет, поэтому чтобы их использовать придется самостоятельно задать функцию-конструктор cons и две функции-селектора: first для первого значения и second для второго. Работают они так:

const pair = cons('left', 'right')
first(pair)  // возвращает 'left'
second(pair)  // возвращает 'right'

Конструктору пары можно передавать другие пары. Таким образом вкладывая пары друг в друга можно создавать сколь угодно сложные типы данных.

Во вчерашнем посте была функция makePoint, которая создает объект, описывающий точку на плоскости. Вот так выглядит ее реализация:

const makePoint = (x, y) => cons(x, y);
const getX = point => first(point);
const getY = point => second(point);

Функции для создания и манипуляции объектами какого-то типа называются «интерфейс». Зачем нужно задавать эти функции, если можно создавать и использовать точки напрямую через cons, first, second?

const point = cons(x, y);
const x = first(point);

Для создания собственных типов данных есть две причины:

  1. Упрощение кода. С точками на плоскости это не так заметно, но когда объект составлен больше чем из двух элементов, то удобнее пользоваться селекторами, чем добираться до внутренностей многократно вложенной пары серией из first и second.

  2. Отделение интерфейса от реализации. Разделять их нужно, чтобы при изменении реализации типов, не нужно было менять код, их использующий. Например если я захочу поменять местами координаты точки в паре, то без интерфейса придется найти все места, где я использую first(point) для нахождения координаты x и заменить на second(point). И наоборот. А если есть интерфейс, то достаточно будет переписать пару функций getX и getY.