用例:我有一个基于XML的小型游戏引擎。每个XML元素都应该被解析。有像<deck>和<dice>这样的元素。现在,我有一个巨大的模式匹配子句,其内容如下
match xml_element with
| Xml.Element ("deck", [("some_attribute", value)], card_children) ->
...
| Xml.Element ("dice", ...它还在继续。我想把它分成模块,这样我就有了一个Deck模块,一个骰子模块,等等。如何正确匹配XML元素的模式并调用不同的模块?如果每个特定模块中没有匹配,那么使用我迭代并返回None的模块列表?
发布于 2020-04-30 14:48:44
Drup (Gabriel Radanne)关于IRC的答复:
let l = [Mod1.f; Mod2.f; Mod3.f]你试一试每一种,按照顺序。
所有函数必须具有相同的签名。
这是“可怜人的模块化模式匹配”:)
但这是一种经典的技术
它最常用于模块化错误处理,特别是在编译器中。
编辑:自动填充列表的一种方法是在每个模块中使用“寄存器函数”( let _ ... )。
发布于 2020-04-29 20:22:58
我建议使用嵌套模式匹配:
match xml_element with
| Xml.Element ("deck", attributes, card_children) -> match attributes with
| [("some_attribute", value)] -> …
| …
| Xml.Element ("dice", attributes, dice_children) -> …
| …然后,您可以将内部函数重构为助手函数,并最终将它们移动到它们自己的模块中。
发布于 2020-04-30 13:03:51
也许可扩展变型能帮你。它们允许您使用+=构造扩展变体类型。假设您有以下类型:
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这允许您在实现其处理时逐步扩展您的类型的。当然,你可以把整个事情分成几个模块。
但是,请注意(从文档中)
可扩展变体类型上的模式匹配需要默认情况来处理未知的变体构造函数。
https://stackoverflow.com/questions/61509954
复制相似问题