首页 > 解决方案 > 如何将大模式匹配拆分为多个模块?

问题描述

用例:我有一个基于 XML 的小型游戏引擎。每个 XML 元素都应该被解析。有<deck>和之类的元素<dice>。现在,我有一个巨大的模式匹配子句,内容如下

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

它继续。我想把它分成模块,这样我就有了一个 Deck 模块,一个 Dice 模块等等。如何正确地对 XML 元素进行模式匹配并调用不同的模块?None如果每个特定模块内没有匹配项,我会迭代并返回一个模块列表?

标签: modulepattern-matchingocaml

解决方案


也许可扩展的变体类型可以帮助你。它们允许您使用+=构造扩展变体类型。假设您有以下类型:

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

这允许您在实现其处理的同时逐步扩展您的类型。当然,您可以将整个事情分成几个模块。

但是,请注意(来自文档)

可扩展变体类型上的模式匹配需要默认情况来处理未知的变体构造函数。


推荐阅读