用例。我有一个基于XML的小型游戏引擎。每个XML元素都要进行解析。有一些元素,比如 <deck>
和 <dice>
. 现在,我有一个巨大的模式匹配子句,内容如下
match xml_element with
| Xml.Element ("deck", [("some_attribute", value)], card_children) ->
...
| Xml.Element ("dice", ...
它继续。我想把它分成几个模块,这样我就有了一个Deck模块,一个Dice模块,等等。我如何正确地在XML元素上进行模式匹配并调用不同的模块?有了一个模块列表,我迭代并返回了 None
如果在每个特定的模块中没有匹配的模块?
我建议使用嵌套模式匹配。
match xml_element with
| Xml.Element ("deck", attributes, card_children) -> match attributes with
| [("some_attribute", value)] -> …
| …
| Xml.Element ("dice", attributes, dice_children) -> …
| …
然后你可以将内部函数重构成辅助函数 最后把它们移到自己的模块中去。
也许 可扩展变体型 可以帮助你。它们允许您使用 +=
构造.比方说你有以下类型。
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
这允许你逐步扩展你的类型。而 实现其处理。当然,你也可以把整个事情分成几个模块。
然而,请注意(从文档中可以看到
在可扩展变体类型上的模式匹配需要一个默认情况来处理未知的变体构造函数。
由 Drup (Gabriel Radanne) 在 IRC 上回答。
let l = [Mod1.f; Mod2.f; Mod3.f]
你可以按顺序尝试每个函数。
所有的函数必须有相同的签名
这是 "穷人的模块化图案匹配":)
但这是一种经典的技术
它最常用于模块化错误处理,特别是在编译器中。
编辑:自动填充列表的方法是通过 "注册功能"。let _ ...
在每个模块中,。