Как разбить большое соответствие шаблону на несколько модулей? - PullRequest
0 голосов
/ 29 апреля 2020

Вариант использования: у меня небольшой игровой движок, основанный на XML. Каждый элемент XML должен быть проанализирован. Есть такие элементы, как <deck> и <dice>. Прямо сейчас, у меня есть огромное предложение соответствия шаблону, которое выглядит так:

match xml_element with
| Xml.Element ("deck", [("some_attribute", value)], card_children) ->
    ...
| Xml.Element ("dice", ...

Это продолжается. Я хочу разделить его на модули, чтобы у меня был модуль Deck, модуль Dice и так далее. Как правильно сопоставить шаблон по элементам XML и вызвать разные модули? Со списком модулей, которые я повторяю и возвращаю None, если нет совпадений внутри каждого конкретного модуля?

Ответы [ 3 ]

0 голосов
/ 30 апреля 2020

Может быть расширяемый вариант типа может помочь вам. Они позволяют расширять тип варианта с помощью конструкции +=. Допустим, у вас есть следующий тип:

type thing = .. (* type thing is open, we can later add constructors to it *)

let handle_thing = function
| _ -> failwith "unknown constructor"

type thing += Dice (* we add the constructor Dice to our type thing *)

let handle_thing = function
  | Dice -> print_string "i handle dice"
  | x -> handle_thing x

type thing += Deck (* we add the constructor Deck to our type thing *)

let handle_thing = function
  | Deck -> print_string "i handle deck"
  | x -> handle_thing x

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

Однако учтите, что (из do c)

для сопоставления с образцом в расширяемом типе варианта требуется значение по умолчанию case для обработки неизвестных вариантов конструкторов.

0 голосов
/ 30 апреля 2020

Ответ от Drup (Gabriel Radanne) на IR C:

let l = [Mod1.f; Mod2.f; Mod3.f]

, и вы попробуете по порядку каждый.

все функции должны иметь одинаковую подпись

это "модульное совпадение бедняков":)

но это классический метод

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

Редактировать: способ автоматического заполнения списка заключается в "функциях регистрации", let _ ..., в каждом модуле.

0 голосов
/ 29 апреля 2020

Я бы порекомендовал использовать сопоставления с вложенными шаблонами:

match xml_element with
| Xml.Element ("deck", attributes, card_children) -> match attributes with
   | [("some_attribute", value)] -> …
   | …
| Xml.Element ("dice", attributes, dice_children) -> …
| …

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...