Учебники

Вяз — Краткое руководство

Вяз — Введение

Вяз это функциональный язык программирования. Он был разработан Эваном Чаплицким в 2012 году.

Elm специально используется для разработки веб-приложений.

Elm компилируется в JavaScript и запускается в браузере. Он быстрый, тестируемый, обслуживаемый и поставляется без исключений времени выполнения.

Некоторые практические применения платформы программирования Elm включают в себя:

  • Игры
  • Графика
  • Одностраничные приложения

Почему вяз

Elm устраняет большинство распространенных проблем, с которыми сталкиваются веб-разработчики. Это включает в себя —

Нет исключений во время выполнения

Вяз это статически типизированный язык. Все возможные ошибки проверяются и исправляются во время компиляции. Это позволяет не иметь исключений во время выполнения.

Сообщения об ошибках для разработчиков

В отличие от других языков программирования, компилятор Elm предназначен для предоставления очень специфичных и удобных для разработчиков сообщений об ошибках во время компиляции. Сообщения об ошибках также включают в себя подсказки, такие как ссылки на рекомендованную проектную документацию.

Легко проверить

Каждая функция Вяза может быть проверена отдельно от всех остальных. Это делает программы, написанные на Elm, легко тестируемыми.

Автоматическое семантическое управление версиями

Elm обеспечивает автоматическое семантическое управление версиями пакетов. Это гарантирует, что изменение патча не приведет к сбою уже запущенного приложения.

Код многократного использования

Функции Elm по своей природе легко использовать повторно по сравнению с функциями в JavaScript, Python или TypeScript.

Вяз — Настройка среды

В этой главе рассматриваются шаги по установке Elm на платформах Windows, Mac и Linux.

Настройка локальной среды

Рассмотрите шаги, показанные ниже, чтобы установить Elm в вашей локальной среде.

Шаг 1 — Установить узел

Поскольку elm скомпилирован в JavaScript, на целевом компьютере должен быть установлен узел . Обратитесь к курсу TutorialsPoint NodeJS за инструкциями по настройке узла и npm.

Настройка узла.

Шаг 2 — Установите вяз

Выполните следующую команду в терминале, чтобы установить elm. Обратите внимание, что стабильная версия elm была 0,18 на момент написания этого курса.

npm install -g [email protected]

Установить вяз

После установки выполните следующую команду, чтобы проверить версию Elm.

C:\Users\dell>elm --version
0.18.0

Шаг 2 — Установите редактор

Используемая здесь среда разработки — Visual Studio Code (платформа Windows).

Visual Studio Code — это IDE с открытым исходным кодом от Visual Studio. Он доступен для платформ Mac OS X, Linux и Windows. VSCode доступен на

https://code.visualstudio.com/.

Установка на Windows

В этом разделе мы обсудим шаги по установке Elm в Windows.

Загрузите https://code.visualstudio.com/. для Windows.

Дважды щелкните файл VSCodeSetup.exe, чтобы запустить процесс установки. Это займет всего минуту.

VSCodeSetup

Вы можете напрямую перейти к пути к файлу, щелкнув правой кнопкой мыши Файл → Открыть в командной строке. Аналогично, опция «Показать в проводнике» показывает файл в проводнике.

Выявить Исследователя

Установка в Mac OS X

Руководство по установке Visual Studio Code для Mac OS X можно найти на VSCode Installation-MAC .

Установка в Linux

Руководство по установке Visual Studio Code Linux для Linux можно найти по адресу VSCode Installation-Linux .

Шаг 4 — Установите удлинитель вяза

Установите удлинитель вяза в VSCode, как показано ниже.

Установка Linux

Elm REPL

REPL расшифровывается как Read Eval Print Loop. Он представляет собой компьютерную среду, такую ​​как консоль Windows или оболочка Unix / Linux, где вводится команда, и система отвечает выводом в интерактивном режиме.

Elm поставляется в комплекте со средой REPL. Он выполняет следующие задачи —

  • Read — читает вводимые пользователем данные, анализирует их в структуру данных elm и сохраняет в памяти.

  • Eval — берет и оценивает структуру данных.

  • Печать — печать результата.

  • Loop — Повторяет указанную выше команду до выхода пользователя. Используйте команду: выход для выхода из REPL и возврата к терминалу.

Read — читает вводимые пользователем данные, анализирует их в структуру данных elm и сохраняет в памяти.

Eval — берет и оценивает структуру данных.

Печать — печать результата.

Loop — Повторяет указанную выше команду до выхода пользователя. Используйте команду: выход для выхода из REPL и возврата к терминалу.

Простой пример добавления двух чисел в REPL показан ниже —

Откройте терминал VSCode и введите команду elm REPL.

Терминал REPL ждет, пока пользователь не введет какой-либо ввод. Введите следующее выражение 10 + 20. Среда REPL обрабатывает ввод, как показано ниже —

  • Читает числа 10 и 20 от пользователя.

  • Оценивает с помощью оператора +.

  • Результат печати 30.

  • Циклы для следующего пользовательского ввода. Здесь мы выходим из цикла.

Читает числа 10 и 20 от пользователя.

Оценивает с помощью оператора +.

Результат печати 30.

Циклы для следующего пользовательского ввода. Здесь мы выходим из цикла.

Elm REPL

Вяз — Базовый синтаксис

В этой главе рассказывается, как написать простую программу на языке вяз.

Шаг 1 — Создайте каталог HelloApp в VSCode

Теперь создайте файл — Hello.elm в этом каталоге.

Создать каталог

На рисунке выше показана папка проекта HelloApp и терминал, открытый в VSCode.

Шаг 2 — Установите необходимые пакеты elm

Менеджер пакетов в elm — это elm-package . Установите пакет elm-lang / html . Этот пакет поможет нам отобразить вывод кода вяза в браузере.

Перейдите к папке проекта HelloApp , щелкнув правой кнопкой мыши Файл → Открыть в командной строке в VSCode.

Выполните следующую команду в окне терминала —

C:\Users\dell\Elm\HelloApp> elm-package install elm-lang/html

Следующие файлы / папки добавляются в каталог проекта при установке пакета.

  • elm-package.json (файл), хранит метаданные проекта
  • elm-stuff (папка), хранит внешние пакеты

Следующее сообщение появится после успешной установки пакета.

пакет установлен

Шаг 3 — Добавьте следующий код в файл Hello.elm

-- importing Html module and the function text
import Html exposing (text)

-- create main method
main =
-- invoke text function
text "Hello Elm from TutorialsPoint"

Вышеуказанная программа отобразит в браузере строковое сообщение Hello Elm из TutorialsPoint .

Для этого нам нужно импортировать текст функции в модуле Html . Функция text используется для печати любого строкового значения в браузере. Основным методом является точка входа в программу. Метод main вызывает текстовую функцию и передает ей строковое значение.

Шаг 4 — Скомпилируйте проект

Выполните следующую команду в окне терминала VSCode.

elm make Hello.elm

Вывод вышеупомянутой команды как показано ниже —

//update path to the proj folder in the command elm make
C:\Users\dell\elm\HelloApp>elm make Hello.elm
Success! Compiled 38 modules.
Successfully generated index.html

Приведенная выше команда создаст файл index.html . Компилятор elm преобразует файл .elm в JavaScript и встраивает его в файл index.html .

Шаг 5 — Откройте index.html в браузере

Откройте файл index.html в любом браузере. Вывод будет таким, как показано ниже —

Открыть браузер

Комментарии в Elm

Комментарии — это способ улучшить читаемость программы. Комментарии могут использоваться для включения дополнительной информации о программе, такой как автор кода, подсказки о конструкции функции и т. Д. Комментарии игнорируются компилятором.

Вяз поддерживает следующие типы комментариев —

  • Однострочные комментарии (-) — любой текст между — и концом строки рассматривается как комментарий.

  • Многострочные комментарии ({- -}) — эти комментарии могут занимать несколько строк.

Однострочные комментарии (-) — любой текст между — и концом строки рассматривается как комментарий.

Многострочные комментарии ({- -}) — эти комментарии могут занимать несколько строк.

иллюстрация

-- this is single line comment

{- This is a
   Multi-line comment
-}

Линии и отступы

Elm не предоставляет фигурные скобки для обозначения блоков кода для определения функций или управления потоком. Блоки кода обозначены отступом строки, который строго соблюдается. Все операторы в блоке должны иметь одинаковый отступ. Например —

module ModuleIf exposing (..)
x = 0

function1 =
   if x > 5 then
      "x is greater"
   else
      "x is small"

Однако следующий блок генерирует ошибку —

-- Create file ModuleIf.elm
module ModuleIf exposing (..)
x = 0

function1 =
   if x > 5 then
      "x is greater"
         else --Error:else indentation not at same level of if statement
      "x is small"

Таким образом, в Elm все непрерывные линии с одинаковым количеством пробелов образуют блок.

C:\Users\admin>elm repl
---- elm-repl 0.18.0 -----------------------------------------------------------
   :help for help, :exit to exit, more at 
   <https://github.com/elm-lang/elm-repl>
   ---------------------------------------
   -----------------------------------------

> import ModuleIf exposing(..) -- importing module from ModuleIf.elm file
>function1 -- executing function from module
-- SYNTAX PROBLEM ---------------------------------------------------

I need whitespace, but got stuck on what looks like a new declaration. 
You are either missing some stuff in the declaration above or just need to add some spaces here:
7| else
   ^
I am looking for one of the following things:

   whitespace

Вяз — Типы данных

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

Вяз это статически типизированный язык. У вяза есть типы, которые похожи на те из других языков.

Число

Числовой тип данных представляет числовые значения. Система типов Elm поддерживает следующие числовые типы:

Старший Тип пример
1 номер — хранит любой номер 7 — это числовой тип
2 Float — хранит дробные значения 7/2 дает 3,5 результата как Float
3 Int — хранит не дробные значения 7 // 2 дает 3 результата как Int

Номер типа вмещает как дробные, так и не дробные значения. Откройте Elm REPL и попробуйте примеры, приведенные ниже —

C:\Users\admin>elm repl
---- elm-repl 0.18.0 
---------------------------------------------
--------------
:help for help, :exit to exit, more at <https://github.com/elm-lang/elm-repl>
------------------------------------------
--------------------------------------
> 7
7 : number
> 7/2
3.5 : Float
> 7//2
3 : Int
>

Строка и Чар

Тип данных String используется для представления последовательности символов. Тип данных Char используется для представления одного символа. Строковые значения определены в двойных кавычках «, а значения Char заключены в одинарные кавычки».

Старший Тип пример
1 String — хранит последовательность символов «TutorialsPoint»
2 Char — хранит дробные значения «Т»

Откройте Elm REPL и попробуйте примеры, приведенные ниже —

C:\Users\admin>elm repl
---- elm-repl 0.18.0 ---------------------------------------
--------------------
:help for help, :exit to exit, more at <https://github.com/elm-lang/elm-repl>
--------------------------------------
------------------------------------------
> "TutorialsPoint"
"TutorialsPoint" : String
> 'T'
'T' : Char

Bool

Тип данных Bool в Elm поддерживает только два значения — True и False. Ключевое слово Bool используется для представления логического значения.

Старший Тип пример
1 Bool — хранит значения True или False 1 == 1 возвращает True

Откройте Elm REPL и попробуйте примеры, приведенные ниже —

C:\Users\dell\elm>elm repl
---- elm-repl 0.18.0 -----------------------------------
------------------------
:help for help, :exit to exit, more at <https://github.com/elm-lang/elm-repl>
----------------------------------------
----------------------------------------
> True
True : Bool
> False
False : Bool
> 1==1
True : Bool
> 1==2
False : Bool
> 1 /= 2 -- not equal
True : Bool
> not True
False : Bool
> not False
True : Bool

Пользовательские типы

Elm поддерживает создание пользовательских типов. Например, рассмотрим платежное приложение. В приложении необходимо хранить различные способы оплаты — кредитная карта, дебетовая карта и банковская сеть. Это может быть достигнуто путем определения пользовательского типа и ограничения его значения тремя приемлемыми способами оплаты.

В следующем примере показано, как создать пользовательский тип.

> type PaymentMode = CreditCard|NetBanking|DebitCard
> payment1 = CreditCard
CreditCard : Repl.PaymentMode
> payment2 = DebitCard
DebitCard : Repl.PaymentMode
> payment3 = UPI
-- NAMING ERROR ---------------------------------------------- repl-temp-000.elm

Cannot find variable `UPI`

7| payment3 = UPI

В приведенном выше примере мы создали пользовательский тип PaymentMode. Переменные payment1 и payment2 присваиваются значениям PaymentMode. Если значение, присвоенное переменной, не соответствует ни одному из значений, определенных типом PaymentMode, приложение выдаст синтаксическую ошибку.

Структурированные типы данных

Структурированные типы данных могут использоваться для хранения нескольких значений в структурированном формате. Elm поддерживает следующие структурированные типы данных —

  • Кортеж
  • Список
  • запись
  • запись

Они будут подробно обсуждаться в следующих главах.

Вяз — Переменные

Переменная по определению является «именованным пространством в памяти», в котором хранятся значения. Другими словами, он действует как контейнер для значений в программе. Переменная помогает программам хранить значения и манипулировать ими.

Переменные в Elm связаны с определенным типом данных. Тип данных определяет размер и расположение памяти переменной, диапазон значений, которые могут храниться в этой памяти, и набор операций, которые можно выполнять с переменной.

Правила именования переменных

В этом разделе мы узнаем о правилах именования переменных.

  • Имена переменных могут состоять из букв, цифр и символа подчеркивания.
  • Имена переменных не могут начинаться с цифры. Он должен начинаться либо с буквы, либо с подчеркивания.
  • Прописные и строчные буквы различны, потому что Elm чувствителен к регистру.

Объявление переменных в вязе

Синтаксис типа для объявления переменной в Elm приведен ниже —

Синтаксис 1

variable_name:data_type = value

Синтаксис «:» (известный как аннотация типа) используется для связи переменной с типом данных.

Синтаксис 2

variable_name = value-- no type specified

Тип данных является необязательным при объявлении переменной в Elm. В этом случае тип данных переменной определяется из присвоенного ей значения.

иллюстрация

В этом примере редактор VSCode используется для написания программы elm и ее запуска с использованием elm repl.

Шаг 1 — Создать папку проекта — VariablesApp. Создайте файл Variables.elm в папке проекта.

Добавьте следующее содержимое в файл.

module Variables exposing (..) //Define a module and expose all contents in the module
message:String -- type annotation
message = "Variables can have types in Elm"

Программа определяет переменные модуля. Имя модуля должно совпадать с именем файла программы elm. Синтаксис (..) используется для отображения всех компонентов в модуле.

Программа объявляет переменное сообщение типа String .

иллюстрация

Шаг 2 — Запустите программу.

  • Введите следующую команду в терминале VSCode, чтобы открыть elm REPL.
elm repl
  • Выполните следующую инструкцию elm в терминале REPL.
> import Variables exposing (..) --imports all components from the Variables module
> message --Reads value in the message varaible and prints it to the REPL 
"Variables can have types in Elm":String
>

иллюстрация

Используйте Elm REPL, чтобы попробовать следующий пример.

C:\Users\dell\elm>elm repl
---- elm-repl 0.18.0 ---------------------------------------
--------------------
:help for help, :exit to exit, more at <https://github.com/elm-lang/elm-repl>
-------------------------------------
------------------------------------------
> company = "TutorialsPoint"
"TutorialsPoint" : String
> location = "Hyderabad"
"Hyderabad" : String
> rating = 4.5
4.5 : Float

Здесь переменные company и location — это строковые переменные, а rating — это переменная типа Float.

Elm REPL не поддерживает аннотации типов для переменных. В следующем примере выдается сообщение об ошибке, если тип данных включен при объявлении переменной.

C:\Users\dell\elm>elm repl
---- elm-repl 0.18.0 -----------------------------------------
------------------
:help for help, :exit to exit, more at <https://github.com/elm-lang/elm-repl>
----------------------------------------
----------------------------------------
> message:String
-- SYNTAX PROBLEM -------------------------------------------- repl-temp-000.elm

A single colon is for type annotations. Maybe you want :: instead? Or maybe you
are defining a type annotation, but there is whitespace before it?

3| message:String
^

Maybe <http://elm-lang.org/docs/syntax> can help you figure it out.

Чтобы вставить разрыв строки при использовании elm REPL, используйте синтаксис \, как показано ниже —

C:\Users\dell\elm>elm repl
---- elm-repl 0.18.0 --------------------------------------
---------------------
:help for help, :exit to exit, more at <https://github.com/elm-lang/elm-repl>
------------------------------------------
--------------------------------------
> company \ -- firstLine
| = "TutorialsPoint" -- secondLine
"TutorialsPoint" : String

Вяз — Операторы

Оператор определяет некоторую функцию, которая будет выполняться над данными. Значения, с которыми работают операторы, называются операндами. Рассмотрим следующее выражение

7 + 5 = 12

Здесь значения 7, 5 и 12 являются операндами, а + и = — операторами.

Основные операторы вяза можно классифицировать как —

  • арифметика
  • реляционный
  • логический

Арифметические Операторы

Предположим, что значения в переменных a и b равны 7 и 2 соответственно.

Показать примеры

Старший оператор Описание пример
1 + (Сложение) возвращает сумму операндов а + б = 9
2 -(Вычитание) возвращает разницу значений аб 5
3 * (Умножение) возвращает произведение значений а * б = 14
4 / (Подразделение поплавков) выполняет операцию деления и возвращает коэффициент с плавающей запятой а / б 3,5
5 // (целочисленное деление) выполняет операцию деления и возвращает целое число а // б = 3
6 % (Модуль) выполняет операцию деления и возвращает остаток % b равен 1

Операторы отношений

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

Предположим, значение a равно 10, а b равно 20.

Показать примеры

Старший оператор Описание пример
1 > Лучше чем (a> b) Неверно
2 < Меньше чем (a <b) верно
3 > = Больше или равно (a> = b) Неверно
4 <= Меньше или равно (a <= b) верно
5 == равенство (a == b) ложно
6 знак равно Не равный (a! = b) верно

Сопоставимые типы

Операторы сравнения, такие как> = или <работают с сопоставимыми типами. Они определяются как числа, символы, строки и списки, кортежи. Сопоставимые типы с обеих сторон оператора должны быть одинаковыми.

Старший Сопоставимый тип пример
1 число 7> 2 дает True
2 персонаж ‘a’ == ‘b’ дает False
3 строка «Привет» == «Привет» дает True
4 кортеж (1, «Один») == (1, «Один») дает Истину
5 список [1,2] == [1,2] дает True

Откройте Elm REPL и попробуйте примеры, показанные ниже —

C:\Users\admin>elm repl
---- elm-repl 0.18.0 -----------------------------------------------------------
:help for help, :exit to exit, more at <https://github.com/elm-lang/elm-repl>
--------------------------------------------------------------------------------
> 7>2
True : Bool
> 7.0>2
True : Bool
> 7.0<2.0
False : Bool
> 'a' > 'b'
False : Bool
> 'a' < 'b'
True : Bool
> "a" < "b"
True : Bool
> (1,2) > (2,3)
False : Bool
> ['1','3'] < ['2','1']
True : Bool
>

Логические Операторы

Логические операторы используются для объединения двух или более условий. Логические операторы тоже возвращают логическое значение.

Показать примеры

Старший оператор Описание пример
1 && Оператор возвращает true, только если все указанные выражения возвращают true (10> 5) && (20> 5) возвращает True
2 || Оператор возвращает true, если хотя бы одно из указанных выражений возвращает true (10 <5) || (20> 5) возвращает True
3 не Оператор возвращает значение, обратное результату выражения. Например,! (> 5) возвращает false. not (10 <5) возвращает True
4 исключающее Оператор возвращает true, только если ровно один вход возвращает true. Оператор возвращает false, если оба выражения возвращают true. xor (10> 5) (20> 5) возвращает false

Вяз — Принятие решений

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

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

Принятие решения

Конструкция принятия решения оценивает условие перед выполнением инструкций. Конструкции для принятия решений в Elm классифицируются следующим образом:

Старший утверждение Описание
1 если … то … еще заявление Оператор if состоит из логического выражения, за которым следует то, которое выполняется, если выражение возвращает истину, и еще, которое выполняется, если выражение возвращает ложь
2 вложенный оператор if Вы можете использовать один, если … тогда … еще внутри другого, если.
3 постановка дела Проверяет значение переменной по списку значений.

если … то … еще заявление

Конструкция if… then оценивает условие перед выполнением блока кода. Если логическое выражение имеет значение true, тогда будет выполнен блок кода внутри оператора then. Если логическое выражение оценивается как ложное, то будет выполнен блок кода внутри оператора else.

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

Синтаксис

if boolean_expression then statement1_ifTrue else statement2_ifFalse

иллюстрация

Попробуйте следующий пример в терминале REPL.

> if 10>5 then "10 is bigger" else "10 is small"
"10 is bigger" : String

Вложенный, если

Вложенный оператор if полезен для тестирования нескольких условий. Синтаксис вложенного оператора if приведен ниже:

if boolean_expression1 then statement1_ifTrue else if boolean_expression2 then statement2_ifTrue else statement3_ifFalse

иллюстрация

Попробуйте следующий пример в Elm REPL —

> score=80
80 : number
> if score>=80 then "Outstanding" else if score > = 70 then "good" else "average"
"Outstanding" : String

Заявление о ситуации

Оператор case может быть использован для упрощения оператора if then else. Синтаксис оператора case приведен ниже.

case variable_name of
   constant1 -> Return_some_value
   constant2 -> Return_some_value
   _ -> Return_some_value if none of the above values match

Оператор case проверяет, соответствует ли значение переменной предварительно определенному набору констант, и возвращает соответствующее значение. Обратите внимание, что значение, возвращаемое каждым регистром, должно быть одного типа. Если значение переменной не совпадает ни с одной из заданных констант, элемент управления передается в * default * (обозначается // _) и возвращается соответствующее значение.

иллюстрация

Попробуйте следующий пример в Elm REPL —

> n = 10
10 : number
> case n of \
| 0 -> "n is Zero" \
| _ -> "n is not Zero"
"n is not Zero" : String

Приведенный выше фрагмент кода проверяет, равно ли значение n нулю. Элемент управления передается по умолчанию, который возвращает строку «n не ноль».

Вяз — петля

Вяз это функциональный язык программирования. Elm использует концепцию рекурсии как альтернативу традиционным циклическим конструкциям.

В этой главе обсуждается концепция рекурсии.

Рекурсия

Некоторые языки программирования позволяют самому себе вызывать модуль или функцию. Этот метод известен как рекурсия.

иллюстрация

В этой программе мы увидим, как использовать рекурсию для отображения hello пять раз.

Шаг 1 — Создайте файл Loop.elm

Создайте модуль Loop и определите функцию sayHello . Функция sayHello принимает целочисленное значение в качестве входных данных и возвращает строковое значение.

module Loop exposing(..)
//function signature
sayHello:Int ->String
//function implementation
sayHello n =
   case n of
   1 -> "Hello:1 "
   _ -> "Hello:" ++ toString (n) ++ " " ++ sayHello(n-1)

Функция sayHello проверяет, был ли передан параметр 1. Если параметр равен 1, то функция вернется, в противном случае она создаст строку Hello и вызовет ту же функцию.

Шаг 2 — вызвать sayHello из REPL

Откройте elm REPL из текущей папки проекта (расположение файла Loop.elm).

//import the module Loop
> import Loop exposing(..)
//invoke the sayHello function with parameter value as 5
> sayHello 5
"Hello:5 Hello:4 Hello:3 Hello:2 Hello:1 Hello:0 " : String
>

Модуль Loop

иллюстрация

В следующем примере печатается сумма из n чисел с использованием рекурсии.

> sumOfNos n =\
| if n==0 then 0 \
| else (n) + sumOfNos (n-1)
<function> : number -> number1

В elm REPL мы создали функцию sumOfNos, которая принимает входное число и суммирует все числа от 0 до этого числа.

Например, если мы передадим input как 5, он будет суммировать 1 + 2 + 3 + 4 + 5, что составляет 15 .

> ssumOfNos 5
15 : number

Вывод программы показан выше.

Вяз — Функции

Функции являются строительными блоками программы Elm. Функция — это набор операторов для выполнения конкретной задачи.

Функции организуют программу в логические блоки кода. После определения функции могут вызываться для доступа к коду. Это делает код многоразовым. Кроме того, функции позволяют легко читать и поддерживать код программы.

Шаги к использованию функции

Есть три шага к использованию функции —

Объявление функции

Объявление функции сообщает компилятору об имени функции, типе возврата и параметрах. Синтаксис объявления функции приведен ниже —

fn_name:data_type_of_the_parameters ->return_type

Объявление функции определяет следующее —

  • Наименование функции.

  • Тип данных параметров. Это необязательно, так как функция может иметь или не иметь параметры.

  • Тип данных значения, которое будет возвращать функция. Функции в Elm всегда должны возвращать значение, так как Elm — это функциональный язык программирования. В отличие от функций в других языках программирования, функции Elm не используют ключевое слово return для возврата значения.

Наименование функции.

Тип данных параметров. Это необязательно, так как функция может иметь или не иметь параметры.

Тип данных значения, которое будет возвращать функция. Функции в Elm всегда должны возвращать значение, так как Elm — это функциональный язык программирования. В отличие от функций в других языках программирования, функции Elm не используют ключевое слово return для возврата значения.

Определение функции или реализация функции

Определение функции обеспечивает фактическое тело функции. Определение функции определяет, как будет выполнена конкретная задача. Синтаксис для определения функции приведен ниже:

fn_name parameter1 parameter2 = statements

Вызов или вызов функции

Функция должна быть вызвана для ее выполнения. Синтаксис для вызова функции приведен ниже —

fn_name parameter1 parameter2

иллюстрация

Следующий код определяет функцию greet. Функция возвращает строку «Hello».

> greet = \
| if True then \
| "Hello" \
| else \
| "GoodBye"
"Hello" : String
> greet
"Hello" : String

Параметризованные функции

Параметры — это механизм для передачи значений в функцию. Значения параметров передаются в функцию во время вызова функции.

Иллюстрация 1

В следующем примере определяется функция fn_add . Функция принимает два числа в качестве параметров и возвращает их сумму. Попробуйте следующее в вязе REPL —

> fn_add x y = x+y
<function> : number -> number -> number
> fn_add 10 20
30 : number

Иллюстрация 2

В следующем примере определяется функция sayHello. Функция sayHello принимает и возвращает значение String в качестве параметра и возвращает String.

> sayHello name = "Hello "++ name
<function> : String -> String
> sayHello "Tutorialspoint"
"Hello Tutorialspoint" : String
>

Трубный оператор

Чтобы понять pipe pipe |>, давайте рассмотрим пример, где у нас есть список различных строк [«a», «b», «c»] . Теперь нам нужна одна строка, которая отделена от —

В следующем примере показано, как это сделать с помощью String.join.

> String.join "-" ["a","b","c","d","e","f"]
"a-b-c-d-e-f" : String

То же действие можно выполнить с помощью оператора pipe |>. Оператор канала может использоваться для объединения нескольких вызовов функций.

> ["a","b","c","d","e","f"] |> String.join "-"
"a-b-c-d-e-f" : String
> ["a","b","c","d","e","f"] |> List.reverse |> String.join "-"
"f-e-d-c-b-a" : String

В первом примере мы объединяем метод list в метод join. Во втором случае тот же список передается для переворота функции, а затем передается для присоединения. Итак, список отображается в перевернутом и объединенном виде.

Вяз — Струна

Последовательность символов Unicode называется String. В Elm строки заключаются в «» двойные кавычки . Строка — это фрагмент текста, как показано ниже.

> "TutorialsPoint"
"TutorialsPoint" : String
> location = "Hyderabad" --variable
"Hyderabad" : String
> location
"Hyderabad" : String
>

Строковые функции

Некоторые общие функции, которые можно использовать для запроса или манипулирования строковыми значениями, приведены ниже. Используйте REPL, чтобы попробовать приведенные ниже примеры.

Старший нет метод Описание
1 isEmpty: String -> Bool строка проверок пуста
2 реверс: строка -> строка переворачивает входную строку
3 длина: строка -> Int возвращает целую длину
4 append: String -> String -> String добавляет две строки и возвращает новую строку
5 append: String -> Sconcat: List String -> String добавляет список строк и возвращает новую строку
6 split: String -> String -> List String разбивает входную строку, используя данный разделитель, возвращает список строк
7 срез: Int -> Int -> String -> String возвращает подстроку с указанием начального, конечного индекса и входной строки
8 содержит: String -> String -> Bool возвращает true, если вторая строка содержит первую
9 toInt: String -> Result.Result String Int разбирает строку на целое число
10 toInt: String -> Result.Result String Int разбирает строку на целое число
11 toFloat: String -> Result.Result String Float разбирает строку, чтобы плавать
12 fromChar: Char -> String создает строку из данного символа.
13 toList: String -> Список символов преобразует строку в список символов
14 fromList: Список символов -> Строка преобразует список символов в строку
15 toUpper: String -> String преобразует входную строку в верхний регистр
16 отделка: Строка -> Строка избавляется от пробелов по обе стороны строки.
17 фильтр: (Char -> Bool) -> String -> String фильтрует набор символов из входной строки
18 карта: (символ -> символ) -> строка -> строка преобразовывает каждый символ во входной строке

пустой

Эта функция может использоваться, чтобы определить, является ли строка пустой. Эта функция возвращает True, если предоставленная строка пуста.

Синтаксис

String.isEmpty String_value

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> String.isEmpty
<function> : String -> Bool

Подпись функции показывает Bool как тип возвращаемого значения и тип ввода как String —

иллюстрация

> String.isEmpty ""
True : Bool
> String.isEmpty "Tutorialspoint"
False : Bool
> location = "Hyderabad"
"Hyderabad" : String
> String.isEmpty location
False : Bool

задний ход

Эта функция переворачивает строку.

Синтаксис

String.reverse String_value

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> String.reverse
<function> : String -> String

Подпись функции показывает String как тип возвращаемого значения и тип ввода как String —

иллюстрация

> String.reverse "TutorialsPoint"
"tnioPslairotuT" : String

длина

Эта функция возвращает длину строки.

Синтаксис

String.length String_value

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> String.length
<function-> : String -> Int

Подпись функции показывает Int как тип возвращаемого значения и тип ввода как String.

иллюстрация

> String.length "Mohtashim"
9 : Int

присоединять

Эта функция возвращает новую строку, добавляя две строки.

Синтаксис

String.append String_value1 String_value2

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> String.append
<function-> : String -> String -> String

Подпись показывает два входных параметра String и один выходной параметр String

иллюстрация

> String.append "Tutorials" "Point"
TutorialsPoint : String

CONCAT

Эта функция возвращает новую строку, объединяя множество строк в одну.

Синтаксис

String.concat [String1,String2,String3]

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> String.concat
<function> : List String -> String

Signature of показывает входной параметр List of String и тип возвращаемого значения String

иллюстрация

> String.concat ["Hello","Tutorials","Point"]
HelloTutorialsPoint : String

Трещина

Эта функция разбивает строку, используя данный разделитель.

Синтаксис

String.split string_seperator String_value

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> String.split
<function> : String -> String -> List String

Подпись показывает два входных параметра String и выводит их в виде списка строкового типа.

иллюстрация

> String.split "," "Hello,Tutorials,Point"
["Hello","Tutorials","Point"] : List String

ломтик

Эта функция возвращает подстроку с указанием начального и конечного индексов. Отрицательные индексы берутся, начиная с конца списка. Значение индекса начинается с нуля.

Синтаксис

String.slice start_index end_index String_value

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> String.slice
<function> : Int -> Int -> String -> String

Подпись показывает три входных параметра и один тип возврата.

иллюстрация

> String.slice 0 13 "TutorialsPoint"
"TutorialsPoin" : String

содержит

Эта функция возвращает True, если вторая строка содержит первую.

Синтаксис

String.contains string1 string2

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> String.contains
<function> : String -> String -> Bool

Подпись показывает тип возврата bool и два входных параметра

иллюстрация

> String.contains "Point" "TutorialsPoint"
True : Bool

toInt

Эта функция преобразует строку в int.

Синтаксис

String.toInt string_value

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> String.toInt
<function> : String -> Result.Result String Int

Поскольку toInt может вернуть ошибку, тип возвращаемого значения — Result, то есть String или Int.

иллюстрация

> String.toInt "20"
Ok 20 : Result.Result String Int
> String.toInt "abc"
Err "could not convert string 'abc' to an Int" : Result.Result String Int

держаться на плаву

Эта функция преобразует строку в число с плавающей точкой.

Синтаксис

String.toFloat string_value

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> String.toFloat
<function> : String -> Result.Result String Float

Поскольку toFloat может возвращать ошибку, тип возвращаемого значения — Result, который является String или Float.

иллюстрация

> String.toFloat "20.50"
Ok 20.5 : Result.Result String Float
> String.toFloat "abc"
Err "could not convert string 'abc' to a Float" : Result.Result String Float

fromChar

Эта функция создает строку из данного символа.

Синтаксис

String.fromChar character_value

Проверить подпись типа функции, следующего в elm REPL —

> String.fromChar
<function> : Char -> String

Подпись показывает String как тип возвращаемого значения и ввод как тип Char

иллюстрация

> String.fromChar 'c'
"c" : String

к списку

Эта функция преобразует строку в список символов.

Синтаксис

String.toList string_value

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> String.toList
<function> : String -> List Char

Функция сигнатуры показывает, возвращает список символов и принимает ввод строки.

иллюстрация

> String.toList "tutorialspoint"
['t','u','t','o','r','i','a','l','s','p','o','i','n','t'] : List Char

fromList

Эта функция преобразует список символов в строку.

Синтаксис

String.fromList list_of_characters

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> String.fromList
<function> : List Char -> String

Функция сигнатуры показывает, возвращает список символов и принимает ввод строки.

иллюстрация

> String.fromList ['h','e','l','l','o']
"hello" : String

TOUPPER

Эта функция преобразует строку в верхний регистр.

Синтаксис

String.toUpper String_value

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> String.toUpper
<function> : String -> String

иллюстрация

> String.toUpper "hello"
"HELLO" : String

снизить

Эта функция преобразует строку во все строчные буквы.

Синтаксис

String.toLower String_value

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> String.toLower
<function> : String -> String

иллюстрация

> String.toLower "AbCd"
"abcd" : String

отделка

Эта функция избавляет от пробелов по обе стороны строки.

Синтаксис

String.trim String_value

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> String.trim
<function> : String -> String

иллюстрация

> String.trim "tutorialspoint "
"tutorialspoint" : String

фильтр

Эта функция фильтрует набор символов из входной строки. Оставьте только символы, которые проходят тест.

Синтаксис

String.filter test_function string_value

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> String.filter
<function> : (Char -> Bool) -> String -> String

Фильтр показывает, что фильтр принимает два входных параметра и возвращает строку. Первый параметр — это функция, которая имеет вход Char и возвращает Bool.

иллюстрация

В этом примере мы передаем Char.isUpper в качестве параметра для метода filter; он возвращает все заглавные буквы, как показано ниже.

> import Char
> String.filter Char.isUpper "abcDEF"
"DEF" : String

карта

Эта функция принимает строку и преобразует каждый символ в строке.

Синтаксис

String.filter mapping_function string_value

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> String.map
<function> : (Char -> Char) -> String -> String

иллюстрация

В следующем примере символ o заменяется на символ @

> String.map (\c -> if c == 'o' then '@' else c) "TutorialsPoint"
"Tut@rialsP@int" : String

Вяз — Список

Структуры данных List, Tuples и Record могут использоваться для хранения коллекции значений.

В этой главе обсуждается, как использовать List в Elm.

Список — это коллекция однородных значений. Все значения в списке должны быть одного типа данных.

Учитывайте следующие ограничения при использовании переменных для хранения значений:

  • Переменные имеют скалярный характер. Другими словами, во время объявления переменная может содержать только одно значение. Это означает, что для хранения n значений в программе потребуется n объявлений переменных. Следовательно, использование переменных неосуществимо, когда нужно хранить большую коллекцию значений.

  • Переменные в программе выделяются памяти в случайном порядке, что затрудняет получение / чтение значений в порядке их объявления.

Переменные имеют скалярный характер. Другими словами, во время объявления переменная может содержать только одно значение. Это означает, что для хранения n значений в программе потребуется n объявлений переменных. Следовательно, использование переменных неосуществимо, когда нужно хранить большую коллекцию значений.

Переменные в программе выделяются памяти в случайном порядке, что затрудняет получение / чтение значений в порядке их объявления.

Синтаксис

List_name = [value1,value2,value3.....valuen]

иллюстрация

В следующем примере показано, как использовать список в Elm. Попробуйте этот пример в elm REPL —

> myList1 = [10,20,30]
[10,20,30] : List number
> myList2 = ["hello","world"]
["hello","world"] : List String

Если мы попытаемся добавить значения разных типов в список, компилятор выдаст ошибку несоответствия типов. Это показано ниже.

> myList = [1,"hello"]
-- TYPE MISMATCH 
--------------------------------------------- 
repl-temp-000.elm

The 1st and 2nd entries in this list are different types of values.

4| [1,"hello"]
^^^^^^^
The 1st entry has this type:
   number
But the 2nd is:
   String

Список операций

Следующая таблица показывает общие операции над списком —

Старший нет метод Описание
1 isEmpty: Список a -> Bool проверяет, пуст ли список
2 реверс: список a -> Bool меняет список ввода
3 длина: список -> Int возвращает размер списка
4 максимум: список сопоставим -> Может быть. Может быть сопоставим возвращает максимальное значение
5 минимум: список сопоставим -> Может быть. Может быть сопоставим возвращает минимальное значение
6 сумма: номер списка -> номер возвращает сумму всех элементов в списке
7 продукт: список номер -> номер проверяет, пуст ли список
8 сортировать: список сопоставимых -> список сопоставимых сортировка списка в порядке возрастания
9 concat: Список (Список a) -> Список a объединяет кучу списка в один
10 append: List a -> List a -> List a объединяет два списка вместе
11 диапазон: Int -> Int -> List Int возвращает список чисел от начала до конца
12 фильтр: (a -> Bool) -> List a -> List a фильтрует список значений из списка ввода
13 руководитель: Список -> Возможно. Может быть возвращает первый элемент из списка
14 tail:: Список a -> Maybe.Maybe (Список a) возвращает все элементы, кроме головы

пустой

Эта функция возвращает true, если список пуст.

Синтаксис

List.isEmpty list_name

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> List.isEmpty
<function> : List a -> Bool

иллюстрация

> List.isEmpty
<function> : List a -> Bool

> List.isEmpty [10,20,30]
False : Bool

задний ход

Эта функция переворачивает список.

Синтаксис

List.reverse list_name

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> List.reverse
<function> : List a -> List a

иллюстрация

> List.reverse [10,20,30]
[30,20,10] : List number

длина

Эта функция возвращает длину списка.

Синтаксис

List.length list_name

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> List.length
<function> : List a -> Int

иллюстрация

> List.length [10,20,30]
3 : Int

максимальная

Эта функция возвращает максимальный элемент в непустом списке.

Синтаксис

List.maximum list_name

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> List.maximum
<function> : List comparable -> Maybe.Maybe comparable

иллюстрация

> List.maximum [10,20,30]
Just 30 : Maybe.Maybe number
> List.maximum []
Nothing : Maybe.Maybe comparable

минимальный

Эта функция возвращает минимальный элемент в непустом списке.

Синтаксис

List.minimum list_name

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> List.minimum
<function> : List comparable -> Maybe.Maybe comparable

иллюстрация

> List.minimum [10,20,30]
Just 10 : Maybe.Maybe number

сумма

Эта функция возвращает сумму всех элементов в списке.

Синтаксис

List.sum list_name

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> List.sum
<function> : List number -> number

иллюстрация

> List.sum [10,20,30]
60 : number

товар

Эта функция возвращает произведение всех элементов в списке.

Синтаксис

List.product list_name

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

<function>  : List number ->  number

иллюстрация

List.product [10,20,30]
6000 : number

Сортировать

Эта функция сортирует значения от самого низкого до самого высокого в списке.

Синтаксис

List.sort list_name

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> List.sort
<function> : List comparable -> List comparable

иллюстрация

> List.sort [10,20,30]
[10,20,30] : List number

CONCAT

Эта функция объединяет несколько списков в один список.

Синтаксис

List.concat [ [list_name1],[list_name2],[list_name3],.....[list_nameN] ]

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> List.concat
<function> : List (List a) -> List a

иллюстрация

> List.concat [[10,20], [30,40],[50,60]]
[10,20,30,40,50,60] : List number

присоединять

Эта функция объединяет два списка.

Синтаксис

List.append [list_name1] [list_name2]

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> List.append
<function> : List a -> List a -> List a

иллюстрация

> List.append [10,20] [30,40]
[10,20,30,40] : List number

Оператор ++ также можно использовать для добавления списка в другой. Это показано в примере ниже —

> [10.1,20.2] ++ [30.3,40.4]
[10.1,20.2,30.3,40.4] : List Float

спектр

Эта функция создает список чисел, каждый элемент увеличивается на единицу. Наименьшее и наибольшее число, которое должно быть в списке, передается функции.

Синтаксис

List.range start_range end_range

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> List.range
<function> : Int -> Int -> List Int

иллюстрация

> List.range 1 10
[1,2,3,4,5,6,7,8,9,10] : List Int

фильтр

Эта функция фильтрует набор значений из списка ввода. Сохраняйте только те значения, которые проходят тест.

Синтаксис

List.filter test_function input_list

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> List.filter
<function> : (a -> Bool) -> List a -> List a

иллюстрация

Следующий пример фильтрует все четные числа из списка ввода

> List.filter (\n -> n%2==0) [10,20,30,55]
[10,20,30] : List Int

голова

Эта функция возвращает первый элемент из списка ввода.

Синтаксис

List.head input_list

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> List.head
<function> : List a -> Maybe.Maybe a

иллюстрация

> List.head [10,20,30,40]
Just 10 : Maybe.Maybe number
> List.head []
Nothing : Maybe.Maybe a

хвост

Эта функция возвращает все элементы после первого в списке.

Синтаксис

List.tail input_list

Чтобы проверить сигнатуру функции, наберите следующее в elm REPL —

> List.tail
<function> : List a -> Maybe.Maybe (List a)

иллюстрация

> List.tail [10,20,30,40,50]
Just [20,30,40,50] : Maybe.Maybe (List number)
> List.tail [10]
Just [] : Maybe.Maybe (List number)
> List.tail []
Nothing : Maybe.Maybe (List a)

Использование оператора Cons

Оператор cons (::) добавляет элемент в начало списка.

иллюстрация

> 10::[20,30,40,50]
[10,20,30,40,50] : List number

Добавляемый новый элемент и тип данных значений в списке должны совпадать. Компилятор выдает ошибку, если типы данных не совпадают.

> [1,2,3,4]::[5,6,7,8]
-- TYPE MISMATCH ---------------------------------
------------ repl-temp-000.elm

The right side of (::) is causing a type mismatch.

3| [1,2,3,4]::[5,6,7,8]
			  ^^^^^^^^^
(::) is expecting the right side to be a:

   List (List number)

But the right side is:

   List number
Hint: With operators like (::) I always check the left side first. If it seems fine, 
I assume it is correct and check the right side. So the 
problem may be in how the left and right arguments interact.

Списки неизменны

Давайте проверим, являются ли списки неизменными в Elm. Первый список myList при объединении со значением 1 создает новый список и возвращается в myListCopy . Поэтому, если мы отобразим начальный список, его значения не будут изменены.

> myList = [10,20,30]
[10,20,30] : List number
> myListCopy = 1::myList
[1,10,20,30] : List number
> myList
[10,20,30] : List number
>myList == myListCopy
False : Bool

Вяз — кортежи

Иногда может возникнуть необходимость хранить коллекцию значений различных типов. Elm дает нам структуру данных под названием tuple, которая служит этой цели.

Кортеж представляет собой разнородную коллекцию значений. Другими словами, кортежи позволяют хранить несколько полей разных типов. Кортеж хранит фиксированное количество значений. Кортежи полезны, когда вы хотите вернуть из функции несколько значений разных типов. Эти структуры данных неизменны, как и другие типы вяза.

Синтаксис

(data1,data2)

Простой пример показан ниже —

> ("TuotrialsPoint",5,True,"Hyderabad")
("TuotrialsPoint",5,True,"Hyderabad") : ( String, number, Bool, String )

В наших последующих разделах мы узнаем о различных операциях кортежей.

первый

Эта операция извлекает первое значение из кортежа.

Синтаксис

Tuple.first tuple_name
> Tuple.first
<function> : ( a1, a2 ) -> a1

иллюстрация

> Tuple.first (10,"hello")
10 : number

второй

Вторая операция кортежа извлекает второе значение из кортежа.

Синтаксис

Tuple.second tuple_name
> Tuple.second
<function> : ( a1, a2 ) -> a2

иллюстрация

> Tuple.second (10,"hello")
"hello" : String

Список кортежей

Список может хранить кортежи. Если кортежи используются внутри списка, убедитесь, что все они имеют одинаковый тип данных и имеют одинаковое количество параметров.

иллюстрация

> [("hello",20),("world",30)]
[("hello",20),("world",30)] : List ( String, number )

Кортеж с функцией

Функция может возвращать кортежи. Кроме того, кортежи могут быть переданы в качестве параметров в функции.

Иллюстрация 1

В следующем примере определяется функция fn_checkEven. Эта функция принимает целочисленное значение в качестве параметра и возвращает кортеж.

> fn_checkEven no = \
   if no%2 == 0 then \
      (True,"The no is Even")\
   else \
      (False,"No is not even")
<function> : Int -> ( Bool, String )
> fn_checkEven 10
(True,"The no is Even") : ( Bool, String )
> fn_checkEven 11
(False,"No is not even") : ( Bool, String )
>

Иллюстрация 2

Следующее передает кортеж в качестве параметра функции.

> fn_add (a,b) = \
| a+b
<function> : ( number, number ) -> number
> fn_add (10,20)
30 : number

Функция fn_add принимает кортеж с 2 числовыми значениями и возвращает их сумму.

деструктурирующие

Разрушение включает в себя разбиение кортежа на отдельные ценности. Чтобы получить доступ к отдельным значениям в кортеже с тремя или более элементами, мы используем деструктуризацию. Здесь мы присваиваем каждое значение в кортеже различным переменным. Используя _, можно определить заполнители для значений, которые будут игнорироваться или пропускаться.

иллюстрация

> (first,_,_) = (10,20,30)
10 : number
> first
10 : number

иллюстрация

В этом примере мы будем использовать синтаксис блока let..in для деструктурирования. Блок let содержит переменные, а блок in содержит выражения, которые должны быть оценены, и значение, которое должно быть возвращено.

> t1 = (10,20,30)
(10,20,30) : ( number, number1, number2 )
> let \
(a,b,c) = t1 \
in\
a + b +c
60 : number

Мы объявляем переменные abc в предложении let и обращаемся к ним с помощью предложения in.

Вяз — Отчеты

Структура данных записи в Elm может использоваться для представления данных в виде пар ключ-значение. Запись может быть использована для организации связанных данных, чтобы обеспечить легкий доступ и обновление данных. Записи вяза похожи на объекты в JavaScript. Элементы данных в записи называются полями.

Определение записи

Используйте следующий синтаксис для определения записи —

Синтаксис

record_name = {fieldname1 = value1, fieldname2 = value2....fieldnameN = valueN}

Запись может хранить данные нескольких типов. Имена полей в записи должны соответствовать общим правилам именования идентификатора Elm.

Доступ к значениям записи

Используйте следующий синтаксис для доступа к отдельным полям в записи.

Синтаксис

record_name.fieldname

ИЛИ ЖЕ

.fieldname record_name

иллюстрация

Попробуйте следующее в Elm REPL —

> company = {name="TutorialsPoint",rating=4.5}
{ name = "TutorialsPoint", rating = 4.5 } : { name : String, rating : Float }
> company.name
"TutorialsPoint" : String
> .rating company
4.5 : Float

Использование записи со списком

Запись может быть сохранена в списке. Все значения полей записи должны быть одного типа.

Синтаксис

list_name = [ {field_name1 = value1},{field_name1 = value2}]

ИЛИ ЖЕ

list_name = [record_name1, record_name2, record_name3....record_nameN]

иллюстрация

Попробуйте следующее в Elm REPL —

> [{name = "Mohtashim"},{name = "kannan"}]
[{ name = "Mohtashim" },{ name = "kannan" }] : List { name : String }
> record1 = {name = "FirstRecord"}
{ name = "FirstRecord" } : { name : String }
> record2 = {name = "SecondRecord"}
{ name = "SecondRecord" } : { name : String }
> recordList = [record1,record2]
[{ name = "FirstRecord" },{ name = "SecondRecord" }] : List { name : String }

Обновить запись

Записи вяза неизменны. Когда запись обновляется, возвращается новая запись с обновленными значениями. Поле может содержать значение другого типа при обновлении записи.

Синтаксис

{record_name | field_name1 = new_value1, field_name2 = new_value2,field_name3 = new_value3....field_nameN = new_valueN}

иллюстрация

Попробуйте следующее в Elm REPL —

> record1 = {name="FirstRecord"}
{ name = "FirstRecord" } : { name : String }
> record1_updated = {record1 | name = "FirstRecordUpdate"}
{ name = "FirstRecordUpdate" } : { name : String }
> record1
{ name = "FirstRecord" } : { name : String }
> record1 == record1_updated
False : Bool

иллюстрация

В следующем примере обновляются несколько полей записи. Попробуйте следующее в Elm REPL —

> record3 = {a = 1,b = 2,c = 3,d = 4,e = 5}
{ a = 1, b = 2, c = 3, d = 4, e = 5 }
: { a : number, b : number1, c : number2, d : number3, e : number4 }
> record4 = {record3 | d=400 ,e=500}
{ a = 1, b = 2, c = 3, d = 400, e = 500 }
: { a : number2, b : number3, c : number4, d : number, e : number1 }
>

Типы псевдоним

Псевдоним типа определяет схему для записи. Другими словами, псевдоним типа определяет, какие поля могут хранить записи, и тип значения, которое эти поля могут хранить. Таким образом, программист не допустит ошибки при пропуске какого-либо определенного атрибута при назначении значений.

Синтаксис

type alias alias_name = {field_name1:data_type,field_name2:data_type,....field_nameN:data_type}

иллюстрация

Выполните следующее в Elm REPL —

> type alias Developer = { name:String,location:String,age:Int}
> dev1 = Developer "kannan" "Mumbai" 20
{ name = "kannan", location = "Mumbai", age = 20 } : Repl.Developer
> dev2 = Developer "mohtashim" "hyderabad" 20
{ name = "mohtashim", location = "hyderabad", age = 20 } : Repl.Developer
>

Теперь, если вы забыли ввести местоположение и возраст, оператор возвращает функцию, которая имеет входные параметры для полей местоположения и возраста.

> dev3 = Developer "Bhagavati"
<function> : String -> Int -> Repl.Developer
We can invoke the function as shown below and pass to it the values for location and age fields.
> dev3 "Pune" 25
{ name = "Bhagavati", location = "Pune", age = 25 } : Repl.Developer

Вяз — Обработка ошибок

Ошибка — любое непредвиденное состояние в программе. Ошибки могут возникать во время компиляции или во время выполнения. Ошибки во время компиляции возникают во время компиляции программы (например, ошибка в синтаксисе программы), в то время как ошибки во время выполнения возникают во время выполнения программы. В отличие от других языков программирования, Elm не выдает ошибок во время выполнения.

Рассмотрим приложение, которое принимает возраст пользователя. Приложение должно выдать ошибку, если возраст равен нулю или отрицателен. В этом случае приложение Elm может использовать концепцию обработки ошибок, чтобы явно выдавать ошибку во время выполнения, если пользователь вводит ноль или отрицательное значение в качестве возраста. Обработка ошибок определяет порядок действий, если во время выполнения программы происходит что-то непредвиденное.

Язык программирования Elm обрабатывает ошибки следующими способами:

  • Может быть
  • Результат

Может быть

Рассмотрим функцию поиска в приложении. Функция поиска возвращает связанные данные, если ключевое слово поиска найдено, иначе ничего не возвращает. Этот вариант использования может быть реализован в Elm с использованием типа MayBe.

Синтаксис

variable_name:MayBe data_type

Переменная типа MayBe может содержать одно из следующих значений:

  • Just some_Value — используется, если есть действительные данные.

  • Ничего — используется, если значение отсутствует или неизвестно. Ничто не эквивалентно нулю в других языках программирования.

Just some_Value — используется, если есть действительные данные.

Ничего — используется, если значение отсутствует или неизвестно. Ничто не эквивалентно нулю в других языках программирования.

иллюстрация

В следующем примере показано, как использовать тип MayBe с переменными и функцией.

Шаг 1 — Создайте файл MayBeDemo.elm и добавьте в него следующий код

-- MayBeDemo.elm
module MayBeDemo exposing(..)
import Maybe

--declaring a MayBe variable and assigning value to it
userName : Maybe String
userName = Just "Mohtashim"

--declaring a MayBe variable and assigning value to it
userAge :Maybe Int
userAge = Just 20

--declaring a MayBe variable and assigning value to it
userSalary:Maybe Float
userSalary = Nothing

--declaring a custom type
type Country = India | China | SriLanka

--defining a function that takes a String parameter as input and returns a value of type MayBe

getCountryFromString : String -> Maybe Country
getCountryFromString p =
case p of
   "India"
      -> Just India
   "China"
      -> Just China
   "SriLanka"
      -> Just SriLanka
   _
      -> Nothing

Шаг 2 — Импортируйте модуль в elm repl и выполните, как указано ниже

E:\ElmWorks\ErroApp> elm repl
---- elm-repl 0.18.0 -----------------------------------------------------------
:help for help, :exit to exit, more at 
--------------------------------------------------------------------------------
> import MayBeDemo exposing(..)
> userName
Just "Mohtashim" : Maybe.Maybe String
> userAge
Just 20 : Maybe.Maybe Int
> userSalary
Nothing : Maybe.Maybe Float
> getCountryFromString "India"
Just India : Maybe.Maybe MayBeDemo.Country
> getCountryFromString "india"
Nothing : Maybe.Maybe MayBeDemo.Country

Функция проверяет, передано ли значение функции Индии или Китаю или ШриЛанке. Если значение параметра не соответствует ни одному из них, оно ничего не возвращает.

Результат

Рассмотрим пример, в котором приложению необходимо проверить некоторое условие и выдать ошибку, если условие не выполняется. Тип Result может быть использован для достижения этой цели. Тип Result должен использоваться, если приложение хочет явно выдать ошибку и вернуть подробности о том, что пошло не так.

Синтаксис

Объявление типа Result принимает два параметра — тип данных об ошибке (обычно String) и тип данных результата, который будет возвращен, если все пойдет хорошо.

type Result error_type data_value_type
= Ok data_value
| Err error_message

Тип Result возвращает одно из следующих значений:

  • Ok some_value — представляет результат, который будет возвращен

  • Err — представляет сообщение об ошибке, которое будет возвращено, если ожидаемые условия не выполнены.

Ok some_value — представляет результат, который будет возвращен

Err — представляет сообщение об ошибке, которое будет возвращено, если ожидаемые условия не выполнены.

Иллюстрация 1

Попробуйте следующий пример в Elm REPL —

> String.toInt
<function> : String -> Result.Result String Int
-- successful result
> String.toInt "10"
Ok 10 : Result.Result String Int
-- unsuccessful result , Error
> String.toInt "a"
Err "could not convert string 'a' to an Int" : Result.Result String Int

Функция String.toInt возвращает целочисленное значение, если переданный параметр является допустимым. Если параметр не является числом, функция возвращает ошибку.

Иллюстрация 2

В следующем примере в качестве параметра принимается возраст. Функция возвращает возраст, если он находится между 0 и 135, в противном случае она возвращает соответствующее сообщение об ошибке.

Шаг 1 — Создайте файл ResultDemo.elm и добавьте в него следующий код.

--ResultDemo.elm
module ResultDemo exposing(..)

userId : Result String Int
userId = Ok 10

emailId : Result String Int
emailId = Err "Not valid emailId"

isReasonableAge : String -> Result String Int
isReasonableAge input =
   case String.toInt input of
      Err r ->
         Err "That is not a age!"

   Ok age ->
      if age < 0 then
         Err "Please try again ,age can't be negative"
      else if age > 135 then
         Err "Please try agian,age can't be this big.."

   else
      Ok age

Шаг 2 — Импортируйте модуль в пакет elm и выполните, как указано ниже

E:\ElmWorks\ElmRepo\15_ErrorHandling\15_Code> elm repl
---- elm-repl 0.18.0 -----------------------------------------------------------
:help for help, :exit to exit, more at <https://github.com/elm-lang/elm-repl>
--------------------------------------------------------------------------------
> import ResultDemo exposing (..)
> userId
Ok 10 : Result.Result String Int
> emailId
Err "Not valid emailId" : Result.Result String Int
> isReasonableAge "10"
Ok 10 : Result.Result String Int
> isReasonableAge "abc"
Err "That is not a age!" : Result.Result String Int

Вяз — Архитектура

В этой главе мы обсудим стандартный способ создания приложений на платформе Elm. В Elm используется архитектурный шаблон, похожий на шаблон Model-View-Controller.

Следующее — четыре главных части Архитектуры Вяза.

  • модель
  • Посмотреть
  • Сообщение
  • Обновить

Архитектура

Как работает архитектура вяза

Модель содержит состояние приложения. Например, если приложение отображает список клиентов, состояние будет содержать данные о каждом клиенте. Чтобы отобразить состояние в презентабельной форме, необходимо создать представление / HTML. Как только пользователь взаимодействует с представлением, нажимая кнопку или вводя данные в форме, представление генерирует сигналы, называемые сообщениями . Сообщения передаются методу обновления , который оценивает сообщения и предпринимает надлежащие действия. Таким образом, метод обновления будет генерировать новую модель.

Новая модель создает новый вид. Представление приведет к новым взаимодействиям от пользователя, чтобы сигнализировать сообщения, которые идут, чтобы обновить функцию. Далее функция создает новую модель. Итак, цикл повторяется, как показано на рисунке выше.

модель

Модель имеет дело с состоянием приложения. Синтаксис для определения модели приведен ниже —

-- Model syntax

type alias Model = {
   property1:datatype,
   proptery2:datatype
...
}

Чтобы создать модель, нам нужно сначала создать шаблон со всеми необходимыми свойствами. Каждое свойство определяет состояние приложения.

Посмотреть

Вид — это визуальное представление состояния приложения. Представление знает, как извлечь данные и создать из них веб-страницу. Когда пользователь взаимодействует с представлением, он может манипулировать состоянием, генерируя сообщения. Синтаксис для определения Представления дан ниже —

--View Syntax
view model =some_implementation

Сообщение

Сообщение — это запрос пользователя на изменение состояния приложения. Сообщения передаются в качестве параметра функции обновления.

--Message Syntax
type Message = Message1 |Message2 ...

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

Обновить

Функция update интерпретирует сообщения, которые передаются ей в качестве параметра, и обновляет модель.

--Update Syntax
update Message_type model =
   some_implementation

Функция обновления принимает сообщение и модель в качестве параметров.

Elm — менеджер пакетов

Диспетчер пакетов — это инструмент командной строки, который автоматизирует процесс установки, обновления, настройки и удаления пакетов в вашем приложении.

Так же, как в JavaScript есть менеджер пакетов под названием npm, в elm есть менеджер пакетов под названием elm-package .

Диспетчер пакетов выполняет следующие три задачи:

  • Устанавливает все зависимости, которые нужны приложению elm
  • Публикует пользовательские пакеты
  • Определяет версию вашего пакета, когда вы готовы к публикации и обновлению.

Elm Package Manager Команды

В следующей таблице перечислены различные команды менеджера пакетов Elm:

Старший команда Синтаксис Описание
1 устанавливать установка elm-пакета Устанавливает пакеты для локального использования
2 публиковать вяз-пакет публиковать Публикует вашу посылку в центральном каталоге
3 удар вяз-пакет Увеличивает номера версий на основе изменений API
4 разница вяз-пакет diff Получает различия между двумя API

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

Иллюстрация — Установка пакета SVG

В этом примере мы увидим, как интегрировать масштабируемую векторную графику (SVG) в приложение Elm.

Шаг 1 — Создайте папку elmSvgApp

Шаг 2 — Установите пакет svg, используя следующую команду —

elm-package install elm-lang/svg

Шаг 3 — Установка Создайте файл SvgDemo.elm и введите содержимое, приведенное ниже. Мы импортируем модуль Svg, чтобы нарисовать прямоугольник размером 100×100 и залить красным цветом.

import Svg exposing (..)
import Svg.Attributes exposing (..)

main =
   svg
   [ width "120"
   , height "120"
   , viewBox "0 0 120 120"
   ]
   [ rect
      [ x "10"
      , y "10"
      , width "100"
      , height "100"
      , rx "15"
      , ry "15"
      ,fill "red"
      ]
      []
   ]

Шаг 4 — Теперь соберите проект, используя elm make. \ SvgDemo.elm. Это сгенерирует index.html, как показано ниже —

построить проект

Вяз — Сообщения

Сообщение является компонентом в архитектуре Вяза. Эти компоненты создаются представлением в ответ на взаимодействие пользователя с интерфейсом приложения. Сообщения представляют собой запросы пользователей на изменение состояния приложения.

Синтаксис

--Message Syntax
type Message = some_message1 |some_message2 ...|some_messageN

llustration

Следующий пример представляет собой простое приложение счетчика. Приложение увеличивает и уменьшает значение переменной на 1, когда пользователь нажимает кнопки «Добавить» и «Вычесть» соответственно.

Приложение будет иметь 4 компонента. Компоненты описаны ниже —

Сообщение

Сообщения для этого примера будут —

type Message = Add | Subtract

модель

Модель представляет состояние приложения. В приложении счетчик определение модели приведено ниже; начальное состояние счетчика будет нулевым.

model = 0

Посмотреть

Представление представляет визуальные элементы приложения. Представление содержит две кнопки (+) и (-). Сообщения «Добавить» и «Вычесть» создаются представлением, когда пользователь нажимает кнопки «+» и «-» соответственно. Измененное значение модели затем отображается представлением.

view model =
-- invoke text function
h1[]
[   div[] [text "CounterApp from TutorialsPoint" ]
   ,button[onClick Subtract] [text "-"]
   ,div[][text (toString model)]
   ,button[onClick Add] [text "+"]
]

Обновить

Этот компонент содержит код, который должен быть выполнен для каждого сообщения, сгенерированного представлением. Это показано в примере ниже —

update msg model =
case msg of
Add -> model+1
Subtract -> model-1

Собираем все вместе

Шаг 1 — Создайте папку MessagesApp и файл MessagesDemo.elm

Шаг 2 — Добавьте следующий код в файл elm —

import Html exposing (..)
import Html.Events exposing(onClick)

model = 0 -- Defining the Model

--Defining the View

view model =
   h1[]
   [  div[] [text "CounterApp from TutorialsPoint" ]
      ,button[onClick Subtract] [text "-"]
      ,div[][text (toString model)]
      ,button[onClick Add] [text "+"]
   ]

--Defining the Messages

type Message = Add | Subtract

--Defining Update

update msg model =
case msg of
   Add -> model+1
   Subtract -> model-1

-- Define the main method
main =
   beginnerProgram
   {
      model=model
      ,view=view
      ,update=update
   }

Шаг 3 — Выполните команду elm make в терминале. Команда elm make компилирует код и генерирует HTML-файл из файла .elm, созданного выше.

C:\Users\dell\elm\MessagesApp> elm make .\MessageDemo.elm
Some new packages are needed. Here is the upgrade plan.

   Install:
      elm-lang/core 5.1.1
      elm-lang/html 2.0.0
      elm-lang/virtual-dom 2.0.4

Do you approve of this plan? [Y/n] y
Starting downloads...

   ΓùÅ elm-lang/html 2.0.0
   ΓùÅ elm-lang/virtual-dom 2.0.4

ΓùÅ elm-lang/core 5.1.1
Packages configured successfully!
Success! Compiled 38 modules.
Successfully generated index.html

Шаг 4 — Откройте index.html и проверьте работу, как показано ниже —

вяз сделать команду

Вяз — Команды

В предыдущих главах мы обсуждали различные компоненты архитектуры Elm и их функции. Пользователь и приложение общаются друг с другом с помощью сообщений.

Рассмотрим пример, в котором приложению необходимо обмениваться данными с другими компонентами, такими как внешний сервер, API, микросервис и т. Д. Для обслуживания запроса пользователя. Это может быть достигнуто с помощью команд в Elm. Сообщения и команды не являются синонимами. Сообщения представляют связь между конечным пользователем и приложением, в то время как команды представляют, как приложение Elm взаимодействует с другими объектами. Команда запускается в ответ на сообщение.

На следующем рисунке показан рабочий процесс сложного приложения Elm —

Workflow

Пользователь взаимодействует с представлением. Представление генерирует соответствующее сообщение на основе действий пользователя. Компонент обновления получает это сообщение и запускает команду.

Синтаксис

Синтаксис для определения команды, как указано ниже —

type Cmd msg

Сообщение, сгенерированное представлением, передается команде.

иллюстрация

В следующем примере выполняется запрос к API и отображается результат из API.

Приложение принимает число от пользователя, передает его в API номеров. Этот API возвращает факты, связанные с числом.

Различные компоненты приложения следующие:

Модуль Http

Модуль Http от Elm используется для создания и отправки HTTP-запросов. Этот модуль не является частью основного модуля. Мы будем использовать менеджер пакетов elm для установки этого пакета.

API

В этом примере приложение будет взаимодействовать с Numbers API — « http://numbersapi.com/#42 ».

Посмотреть

Вид приложения содержит текстовое поле и кнопку.

view : Model -> Html Msg
view model =
   div []
      [ h2 [] [text model.heading]
      ,input [onInput Input, value model.input] []
      , button [ onClick ShowFacts ] [ text "show facts" ]
      , br [] []
      , h3 [][text model.factText]
      ]

модель

Модель представляет значение, введенное пользователем, и результат, который будет возвращен API.

type alias Model =
   { heading : String
   , factText : String
   , input :String
   }

Сообщение

Приложение имеет следующие три сообщения —

  • ShowFacts
  • вход
  • NewFactArrived

После нажатия кнопки « Показать факты» сообщение ShowFacts передается методу обновления. Когда пользователь вводит какое-либо значение в текстовое поле, сообщение ввода передается методу обновления. Наконец, когда ответ сервера Http получен, сообщение NewFactArrived будет передано для обновления.

type Msg
   = ShowFacts
   |Input String
   | NewFactArrived (Result Http.Error String)

Обновить

Метод update возвращает кортеж, который содержит объекты модели и команды. Когда пользователь нажимает кнопку «Показать факты», сообщение передается обновлению, которое затем вызывает NumbersAPI.

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
   case msg of
      Input newInput ->
      (Model "NumbersApi typing.." "" newInput ,Cmd.none)
      ShowFacts ->
         (model, getRadmonNumberFromAPI model.input)

      NewFactArrived (Ok newFact) ->
         (Model "DataArrived" newFact "", Cmd.none)

      NewFactArrived (Err _) ->
      (model, Cmd.none)

Вспомогательная функция

Вспомогательная функция getRandomNumberFromAPI вызывает NumbersAPI и передает ему число, введенное пользователем. Результат, возвращаемый API, используется для обновления модели.

getRadmonNumberFromAPI : String->Cmd Msg
getRadmonNumberFromAPI newNo =
   let
      url =
         "http://numbersapi.com/"++newNo
   in
      Http.send NewFactArrived (Http.getString url)
Старший метод Подпись Описание
1 Http.getString getString: String -> Строка запроса Создайте запрос GET и интерпретируйте тело ответа как строку.
2 Http.send отправить: (Ошибка результата a -> msg) -> Запрос a -> Cmd msg Отправить запрос Http.

главный

Это точка входа в проект Elm.

main =
   Html.program
      { init = init
      , view = view
      , update = update
      , subscriptions = subscriptions
      }

Собираем все вместе

Шаг 1 — Создайте папку CommandApp и файл CommandDemo.elm.

Шаг 2 — Установите модуль http с помощью команды elm package install elm-lang / http .

Шаг 2 — Введите содержимое для CommandDemo.elm, как показано ниже —

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Http

main =
   Html.program
      { init = init
      , view = view
      , update = update
      , subscriptions = subscriptions
      }

-- MODEL
type alias Model =
   { heading : String
   , factText : String
   , input :String
   }

init : (Model, Cmd Msg)
init =
   ( Model "NumbersAPI" "NoFacts" "42"-- set model two fields
   , Cmd.none -- not to invoke api initially
   )

-- UPDATE

type Msg
   = ShowFacts
   |Input String
   | NewFactArrived (Result Http.Error String)

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
   case msg of
      Input newInput ->
      (Model "NumbersApi typing.." "" newInput ,Cmd.none)
      ShowFacts ->
         (model, getRadmonNumberFromAPI model.input)

      NewFactArrived (Ok newFact) ->
         (Model "DataArrived" newFact "", Cmd.none)

      NewFactArrived (Err _) ->
         (model, Cmd.none)

- VIEW

view : Model -> Html Msg
view model =
   div []
      [ h2 [] [text model.heading]
      ,input [onInput Input, value model.input] []
      , button [ onClick ShowFacts ] [ text "show facts" ]
      , br [] []
      , h3 [][text model.factText]
      ]

-- SUBSCRIPTIONS

subscriptions : Model -> Sub Msg
subscriptions model =
   Sub.none

-- HTTP

getRadmonNumberFromAPI : String->Cmd Msg
getRadmonNumberFromAPI newNo =
   let
      url =
      "http://numbersapi.com/"++newNo
   in
      Http.send NewFactArrived (Http.getString url)

Шаг 4 — Запустите команду.

C:\Users\dell\elm\CommandApp> elm make .\CommandDemo.elm

Это сгенерирует HTML-файл, как показано ниже.

Создать HTML

Вяз — Подписки

В предыдущей главе мы обсуждали, что представление взаимодействует с другими компонентами с помощью команд. Аналогично, компонент (например, WebSocket) может взаимодействовать с представлением с использованием подписок. Подписки — это способ, которым приложение Elm может получать внешние входные данные, такие как события клавиатуры, события таймера и события WebSocket.

На следующем рисунке показана роль подписок в приложении Elm. Пользователь взаимодействует с приложением Elm через сообщения. Данное приложение использует WebSocket и имеет два режима работы:

  • Отправить данные на стороне клиента на сервер сокетов с помощью команды
  • Получать данные в любое время с сервера сокетов через подписку

сервер сокетов

Синтаксис

Синтаксис для определения подписки приведен ниже —

type Sub msg

иллюстрация

Давайте разберемся с подписками на простом примере.

В приведенном ниже примере приложение отправляет сообщение на сервер. Сервер является эхо-сервером, который отвечает клиенту тем же сообщением. Все входящие сообщения позже отображаются в списке. Мы будем использовать WebSocket (протокол wss), чтобы иметь возможность непрерывно прослушивать сообщения с сервера. WebSocket будет отправлять пользовательский ввод на сервер с помощью команд, в то время как он будет использовать подписку для получения сообщений от сервера.

Различные компоненты приложения приведены ниже —

Эхо сервер

Доступ к эхо-серверу можно получить по протоколу wss. Эхо-сервер отправляет обратно пользовательский ввод в приложение. Код для определения эхо-сервера приведен ниже —

echoServer : String
echoServer =
"wss://echo.websocket.org"

модель

Модель представляет вводимые пользователем данные и список входящих сообщений с сервера сокетов. Код для определения модели приведен ниже.

type alias Model =
   { input : String
   , messages : List String
   }

Сообщения

Тип сообщения будет содержать Ввод для ввода текста от пользователя. Сообщение Send будет сгенерировано, когда пользователь нажмет кнопку, чтобы отправить сообщение на сервер WebSocket. NewMessage используется, когда сообщение приходит с эхо-сервера.

type Msg
   = Input String
   | Send
   | NewMessage String

Посмотреть

Вид приложения содержит текстовое поле и кнопку отправки для отправки пользовательского ввода на сервер. Ответ от сервера отображается в представлении с использованием тега div .

view : Model -> Html Msg
view model =
   div []
      [ input [onInput Input, value model.input] []
      , button [onClick Send] [text "Send"]
      , div [] (List.map viewMessage (List.reverse model.messages))
      ]

viewMessage : String -> Html msg
viewMessage msg =
   div [] [ text msg ]

Обновить

Функция обновления принимает сообщение и компоненты модели. Обновляет модель в зависимости от типа сообщения.

update : Msg -> Model -> (Model, Cmd Msg)
update msg {input, messages} =
   case msg of
      Input newInput ->
         (Model newInput messages, Cmd.none)

   Send ->
      (Model "" messages, WebSocket.send echoServer input)

   NewMessage str ->
      (Model input (str :: messages), Cmd.none)
Старший метод Подпись Описание
1 WebSocket.listen прослушать: String -> (String -> msg) -> Sub msg Подписывается на любые входящие сообщения на веб-сокете.
2 WebSocket.send отправить: String -> String -> Cmd msg Отправляет запрос wss на адрес сервера. Важно, чтобы вы также подписались на этот адрес с помощью listen. Если нет, веб-сокет будет создан для отправки одного сообщения, а затем закрыт.

Подписка

Функция подписки принимает объект модели. Чтобы получать сообщения от сервера WebSocket, мы вызываем WebSocket.listen, передавая сообщение как NewMessage . Когда с сервера приходит новое сообщение, вызывается метод обновления.

subscriptions : Model -> Sub Msg
subscriptions model =
WebSocket.listen echoServer NewMessage

главный

Основная функция — это точка входа в приложение elm, как показано ниже.

main =
   Html.program
      { init = init
      , view = view
      , update = update
      , subscriptions = subscriptions
      }

Собираем все вместе

Шаг 1 — Создайте каталог SubscriptionApp и добавьте в него файл SubscriptionDemo.elm.

Шаг 2 — Добавьте следующее содержимое в файл SubscriptionDemo.elm —

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import WebSocket

main =
   Html.program
      { init = init
      , view = view
      , update = update
      , subscriptions = subscriptions
      }

echoServer : String
echoServer =
   "wss://echo.websocket.org"

-- MODEL

type alias Model =
   { input : String
   , messages : List String
   }

init : (Model, Cmd Msg)
init =
   (Model "" [], Cmd.none)

-- UPDATE
type Msg
   = Input String
   | Send
   | NewMessage String

update : Msg -> Model -> (Model, Cmd Msg)
update msg {input, messages} =
   case msg of
      Input newInput ->
      (Model newInput messages, Cmd.none)

   Send ->
      (Model "" messages, WebSocket.send echoServer input)

   NewMessage str ->
      (Model input (str :: messages), Cmd.none)

-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
   WebSocket.listen echoServer NewMessage

-- VIEW
view : Model -> Html Msg
view model =
   div []
      [ input [onInput Input, value model.input] []
      , button [onClick Send] [text "Send"]
      , div [] (List.map viewMessage (List.reverse model.messages))
      ]

viewMessage : String -> Html msg
viewMessage msg =
div [] [ text msg ]

Шаг 3 — Установите пакет websockets с помощью менеджера пакетов elm.

C:\Users\dell\elm\SubscriptionApp> elm-package install elm-lang/websocket

Шаг 4 — Создайте и сгенерируйте файл index.html, как показано ниже.

C:\Users\dell\elm\SubscriptionApp> elm make .\SubscriptionDemo.elm

Шаг 5 — После выполнения будет сгенерирован следующий вывод: