Создание структуры данных в Elm

Советы по созданию структуры данных в Elm и практические примеры реализации.

Это конспект видео по elm. Я делаю такие конспекты, чтобы лучше запоминать материал и легче найти обсуждаю проблему, если мне будет необходимо вернуться к ней в будущем.

Сегодня, законспектируем доклад «Make Data Structures» by Richard Feldman

Richard Feldman на Elm Europe 2018

Ричард работал над редактором для написания книги. В докладе он рассказывает о советах, которые бы он дал себе «прошлому». То есть, какие уроки он вынес приобретя опыт работы в Elm.

Некоторые мысли:

  • думать о структуре данных;
  • не бить код на модули, как в react (про это было и в докладе Life of file);
  • попробовать и «замараться», затем попытаться сделать лучше;

Совет себе прошлому #1: Делать структуру данных

  • придумывайте структуру данных, которая отражает UI;
  • делайте интерфейс. Делайте «невозможное состояние», невозможным, продумывайте как взаимодействуют части модели;
  • отображайте UI (не сразу, а только когда готова структура данных + интерфейс). Обычно, мы сразу начинаем с отображения, а потом думаем о данных. Здесь нужно наоборот.

С 25:45 начинается рассказ про моделирование структуры данных на примере Dreamwriter (редактора, который Ричард делал).

Когда моделируется структура данных, и есть maybe тип, то можно разложить всего его варианты. В докладе, например идет: Loading (Maybe Doc) (Maybe Problem). Стоит подумать, а действительно ли все эти комбинации 2х maybe могут быть?

варианты maybe типов в Elm в разложенном виде

Совет: начинайте с создания типа вручную, и затем, если видите какой-то патерн — используйте готовые типы. На деле это было так: Loading (Maybe Doc, Maybe Problem) (где maybe «готовый тип») превратилось в «созданный вручную»:

Как видим, Loading тип преобразился и отображает только возможные состояния.

Ричард рекомендует работать по схеме: build -> discover -> refactor. Что подразумевает: что-то сделали, сбилдили. Затем посмотрели как оно работает, вынесли какую-то новую информацию. Если видим, что нужно менять — отрефакторили.

Далее, в примере про view приводится еще один паттерн в Elm — build top level helpers (делайте хэлпер функции высшего порядка). Например:

Здесь, viewLoadedtop level helper. Так же стоит обратить внимание, на то, что у типа Loaded появился один аргумент типа LoadedModel, это record, куда были спрятаны все необходимые свойства. Конкретно для этого доклада, это:

С 39:36 начинается обсуждение моделирования типа Doc (документ, ядро приложения). Причем, сразу же выносится в отдельный модуль.

Началось обсуждение вариантов описания типа для id документа. Если сделать просто type alias DocId = Int, то можем получить не то, что ожидаем:

баг с плохим описанием типа в Elm

Обратите внимание, на getRelated. Аргументы doc.docId и resultsPerPage перепутаны местами, но так как они оба Int — компилятор не будет ругаться и все «сбилдится». Type alias docId в процессе билда превратится в Int. Рантайм ошибки не будет (не бывает в Elm), однако приложение работает не так, как мы ожидаем.

Решение — использовать кастомный тип:

Перед нами кастомный тип с одним вариантом. Но он сразу же закроет проблему, если аргументы будут переданы не в нужном порядке. Так как DocId будет содержать декодер и энкодер — выделяем в отдельный файл, т.е. модуль.

Так же, Ричард не expose (выставляет наружу) из модуля DocId конструктор типа, в итоге получаем opaque type.

opque type elm

Opaque type (не прозрачный тип) позволяет скрыть внутреннюю реализацию. Вы не сможете пройтись pattern matching’ом по этому типу, что-то поменять внутри… Вы можете работать с DocId только через то, что «экспозится» наружу, в нашем случае это функции encode и decode + сам тип DocId.

В случае с Problem, которая тоже уехала в отдельный модуль, Ричард экспортирует конструктор типа, потому что он хочет использовать «pattern matching» на данном Enum типе.

enumeration type elm

На 46:50 идет речь о том, как можно выставить наружу интерфейс для изменения полей внутри opaque типа в виде record: можно создать функции «мапперы».

В конце показан заключительный слайд «Make Data Structure»:

  • начинайте с type (с описания типа)
  • используйте opaque тип по умолчанию (в процессе, решайте нужно вам наружу выставлять конструктор или нет, если нет — то пусть остается opaque).
Понравилась статья? Поделиться с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: