Давайте есть определение типа для дерева с несколькими типами бинарных узлов, среди других типов узлов, т.е.Подмножества членов Союза, как «параметр» в шаблоне сопоставления
type Tree =
| BinaryNodeA of Tree * Tree
| BinaryNodeB of Tree * Tree
| [Other stuff...]
Я хочу, чтобы управлять этим деревом используя рекурсивную функцию, которая могла бы, например, заменять подносы любого типа двоичного узла (путем создания нового узла). Проблема, которая сводит меня с ума: как сопоставить все BinaryNodes, чтобы аромат Node стал «параметром», чтобы иметь общий своп, который может быть применен к любому аромату 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 для Fsacc/Fslex-сгенерированного парсера/lexer, что ограничивает возможности его реструктуризации. Есть идеи?
Зачем вам нужны несколько конструкторов для 'BinaryNode'? Не могли бы вы изменить его на один конструктор с дополнительным элементом 'Tag', который кодирует информацию, например. 'BinaryNode тега * Tree * Tree' и' type Tag = A | B'? – Lee