Форум программистов, компьютерный форум, киберфорум
loothood
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  

Пятничный Elm (Часть VI)

Запись от loothood размещена 27.01.2016 в 17:41
Показов 1795 Комментарии 0

Пятничный Elm. Аннотации Типов (Часть VI)

Одна из основных характеристик Elm - система статической типизации. Благодаря статической типизации, никогда не произойдет ошибок вида "runtime exception", если программа прошла стадию компиляции. В данной заметке мы рассмотрим систему типов и аннотацию типов более подробно.


О серии "Пятничный Elm"

Это шестой пост серии заметок о языке программирования Elm.
Цель данной серии - дать читателям знания от уровня "Что такое Elm" до "Гуру Elm", шаг за шагом.


Описания типов против интерфейса типов

Не смотря на то что Elm - статически типизированный язык, в предыдущих статьях мы не описывали типы данных. Причина в том, что Elm может определить тип практически любого выражения самостоятельно. Давайте вспомним некоторые функции из предыдущей статьи и перепишем их с описанием типов. Тип функции объявляется в строке выше самой функции:
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import Html
 
multiply : number -> number -> number
multiply a b = a * b
 
square : number -> number
square a = multiply a a
 
productOfSquares : number -> number -> number
productOfSquares a b = multiply (square a) (square b)
 
incrementAll : List number -> List number
incrementAll list = List.map (\ n -> n + 1) list
 
incrementAll2 : List number -> List number
incrementAll2 = List.map (\ n -> n + 1)
 
main : Html.Html
main =
  let
    print n = Html.text <| toString n
  in
    Html.p []
    [ print <| multiply 3 5
    , Html.br [] []
    , print <| square 4
    , Html.br [] []
    , print <| productOfSquares 2 3
    , Html.br [] []
    , print <| incrementAll [1, 2, 3]
    , Html.br [] []
    , print <| incrementAll2 [1, 2, 3]
    ]
Я немного переписал функцию main - убрал дублирование преобразования из числа/списка в HTML text

Для примера рассмотрим участок кода square : number -> number - это аннотация для определения функции square. Аннотация типов должна располагаться на строку выше, чем определение функции. Она состоит из имени функции, двоеточия и типов всех входных и выходных параметров, разделенных между собой стрелкой ->.

Обратите внимание что в аннотации нет различий между входными и выходными параметрами. Например, для функции multiply, в аннотации описаны три переменных типа number. Если вы изучали другие языки программирования, то, возможно, думали что аннотация для этой функции должна выглядеть так: (number, number) -> number, но это не так. Разделитель первых двух входных параметров -> точно такой же как и между вторым входным и выходным параметрами. Объясняется это каррированием. Другими словами, функция multiply принимает на вход только один параметр и возвращает функцию с аннотацией number -> number. Для иллюстрации:

Haskell
1
2
3
4
5
6
7
8
9
10
import Html
 
multiply : number -> number -> number
multiply a b = a * b
 
multiplyByFive : number -> number
multiplyByFive = multiply 5
 
main : Html.Html
main = multiplyByFive 3 |> toString |> Html.text

Композиция типов

Давайте рассмотрим остальные функции из предыдущей статьи(и их аннотации типов):

Haskell
1
2
3
4
5
incrementAll : List number -> List number
incrementAll list = List.map (\ n -> n + 1) list
 
incrementAll2 : List number -> List number
incrementAll2 = List.map (\ n -> n + 1)
Эти функции работают со списками. Когда идет речь о списках, очень важным является тип элементов списка. Потому мы объявили что тип параметров не просто List, а List number, так как список состоит из элементов типа number. Данный пример - пример основной концепции работы с типами данных, использующейся в Elm. Наиболее часто данная концепция встречается в контейнерах(таких как List или Maybe), и обычно, определяет какого типа элементы могут содержаться в этих структурах данных.


Генерация аннотации типов автоматически

Можно переложить на плечи компилятора задачу по определению типов функций и переменных. Для этого, надо скомпилировать код без аннотации типов с флагом --warn.
Например, если скомпилировать код из предыдущей заметки:
elm-make --warn Fuctions.elm

Bash
1
2
3
4
5
6
7
8
9
10
11
=================================== WARNINGS ===================================
 
-- missing type annotation -------------------------------------- Functions.elm
 
Top-level value `multiply` does not have a type annotation.
 
3│ multiply a b = a * b
   ^^^^^^^^^^^^^^^^^^^^
I inferred the type annotation so you can copy it into your code:
 
multiply : number -> number -> number
Прекрасно не так ли?


Подведем итоги

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

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

оригинал
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
Debian 13: Установка Lazarus QT5
ВитГо 09.05.2026
Эта инструкция моя компиляция инструкций volvo https:/ / www. cyberforum. ru/ blogs/ 203668/ 10753. html и его же старой инструкции по установке Lazarus с gtk2. . .
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2. Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru