Добрался до Web:) А именно до Elm, который построен на идиоме функционального реактивного программирования. Это такой подход в котором с одной стороны функциональная чистота и декларативность, а с другой удобность построения интерактивного графического интерфейса. Вещи, которые могут изменятся, представляются в виде сигналов. А вся программа представляется в виде pure functional зависимостей между сигналами.
Приведу очень простой пример с WebSocket. Для этого нужен сервер который принимает сообщения, складирует их у себя и возвращает все склеенные через разделитель (конец строки). Я использовал cowboy на Erlang. Приложение тут.
Создаем поле и кнопку. Функция создания поля возвращает два объекта: сигнал графических элементов и сигнал строк. Сигнал графических элементов, а не просто графический элемент нужен потому, что поле может изменятся. А сигнал строк — это значения. Кнопка не изменяется, поэтому возвращается просто графический элемент и сигнал нажатий.
(newItemField, newItemData) = Graphics.Input.field "" (newItemButton, newItemPressed) = Graphics.Input.button "Add Item"
Далее фильтруем сигнал данных. Результат — это сигнал, который состоит из данных второго поля, которые возникают во время нажатия кнопки.
filteredData : Signal String filteredData = newItemPressed `sampleOn` newItemData
Функция beside возвращает элемент, который состоит из входных, размещенных определенным образом. Поскольку она работает на элементах, а у нас сигналы элементов, то нужно использовать функции схожие с map и foreach в других языках. По типу легко понять предназначение.
inputs : Signal Element inputs = beside <~ newItemField ~ constant newItemButton
Далее подключаемся к серверу. Функция подключения принимает адрес сервера и сигнал входных сообщений (строк). Результатом есть сигнал ответов сервера. Посылка и прием сообщений асинхронный.
response : Signal String response = WebSocket.connect "ws://localhost:8080/websocket" filteredData
Парсим ответ, разделяя его на строки, далее каждую строку с помощю plainText превращаем в графический элемент, далее все элементы размещаем попорядку сверху вниз.
outputs : Signal Element outputs = flow down . map Text.plainText . split "\n" <~ response
Далее размещаем поле и кнопку над результирующим списком и все готово. Простенько и со вкусом.
main : Signal Element main = above <~ inputs ~ outputs
П.С. Спасибо Максиму за популяризацию Elm и Erlang среди меня.
Немає коментарів:
Дописати коментар