Подмножество членов Союза как "параметр" в сопоставлении с образцом
Давайте определим тип для дерева с несколькими типами бинарных узлов среди других типов узлов, т.е.
type Tree =
| BinaryNodeA of Tree * Tree
| BinaryNodeB of Tree * Tree
| [Other stuff...]
Я хочу манипулировать этим деревом, используя рекурсивную функцию, которая может, например, менять подузлы любого типа двоичного узла (путем создания нового узла). Проблема, которая сводит меня с ума: как сопоставить все BinaryNodes, чтобы аромат узла стал "параметром", чтобы иметь общий обмен, который можно применить к любому вкусу BinaryNode для возврата замененного узла этого вкуса?
Я знаю, как сопоставить все деревья, которые являются BinaryNodes, используя активный шаблон:
let (|BinaryNode|_|) (tree : Tree) =
match tree with
| BinaryNodeA _ | BinaryNodeB _ -> Some(tree)
| _ -> None
Но этого недостаточно, потому что следующее не представляется достижимым:
match tree with
| [cases related to unary nodes..]
| BinaryNode a b -> BinaryNode b a
Другими словами, я не нашел способа использовать аромат BinaryNode, как если бы это был параметр, подобный a и b. Вместо этого кажется, что я должен сопоставить каждый вариант BinaryNode отдельно. Это могло бы иметь практическое значение, если бы существовало большое количество разновидностей бинарных узлов. Дерево типов - это AST для синтаксического анализатора / лексера, сгенерированного Fsyacc/Fslex, что ограничивает возможности его реструктуризации. Есть идеи?
1 ответ
Вам просто нужно изменить определение вашего активного шаблона:
type Flavor = A | B
let (|BinaryNode|_|) (tree : Tree) =
match tree with
| BinaryNodeA(x,y) -> Some(A,x,y)
| BinaryNodeB(x,y) -> Some(B,x,y)
| _ -> None
let mkBinaryNode f t1 t2 =
match f with
| A -> BinaryNodeA(t1,t2)
| B -> BinaryNodeB(t1,t2)
Тогда вы можете достичь того, что вы хотите, как это:
match tree with
| [cases related to unary nodes..]
| BinaryNode(f,t1,t2) -> mkBinaryNode f t2 t1
Но если это общая потребность, то, возможно, имеет смысл изменить определение Tree
включать аромат вместо того, чтобы иметь дело с этим, используя активные образцы.