Понимание общих типов профсоюзов в Elm

У меня возникли проблемы с пониманием того, что такое тип Html msg или как он используется. Я нашел эту строку кода в VirtualDom.elm, которая Html msg представляется псевдонимом:

type Node msg = Node

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

  • Как функция div создает один из этих объектов?
  • Как используется такой объект?
  • Как можно использовать такой объект?
  • Есть ли какое-либо значение для пользователя, чтобы определить тип, подобный этому, или Html msg просто магический тип для поддержки компилятора/времени Elm?

Ответ 1

Html msg является Type Alias ​​ для Node msg, который является Тип универсального союза

Тип соединения Node msg

Имеет смысл рассуждать о сигнатуре типа Node msg в контексте Elm Architecture, где все сообщения для вашего приложения, кроме флагов для Http.App.programWithFlags, происходят через сообщения.

msg Тип переменной в Node msg только намекает на мысль о том, что все сообщения из вашего DOM-поддерева должны принадлежать одному типу объединения.

node
    :  String
    -> List (Attribute msg)
    -> List (Html msg)  -- List of children nodes with a msg
    -> Html msg         -- Produced DOM node

Функция div использует общие типы Union

Благодаря переменной типа msg, компилятор Elm знает, когда ваше дерево DOM корректно в контексте архитектуры Elm.

В мире JavaScript Node значение Node msg Тип соединения представляет объект со следующей структурой:

{  
   "type":"node",
   "tag":"div",
   "facts":{},            // Attributes and DOM events
   "children":[],         // Children, have the same structure
   "descendantsCount": 0  // Used for Virtual DOM diffing
}

Как вы можете использовать общие типы Union

Большинство сложных структур данных ядра реализованы с использованием общих типов Union, проверьте Maybe или Dict, чтобы получить вдохновение.

Html msg и пользовательские общие типы Union

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

type List a =
  Empty | Node a (List a)