Могут ли дискриминационные союзы ссылаться друг на друга?

Я строю дерево выражений, используя дискриминированные объединения. Код ниже:

type IntExpression =
    | TrueIsOne of BoolExpression

type BoolExpression =
    | LessThan of IntExpression * IntExpression
    | And of BoolExpression * BoolExpression
    | Or of BoolExpression * BoolExpression
    | Bool of bool

вызывает ошибку, поскольку BoolExpression не определен. Обмен определениями приводит к обратному (IntExpression не определяется), как и следовало ожидать.

Есть ли способ обойти это?

Ответ 1

Да, используйте and для определения типов групп с взаимозависимостями:

type IntExpression =
    | TrueIsOne of BoolExpression

and BoolExpression =
    | LessThan of IntExpression * IntExpression
    | And of BoolExpression * BoolExpression
    | Or of BoolExpression * BoolExpression
    | Bool of bool

Ответ 2

"и" работает обычно для типов с взаимными зависимостями. То есть он работает для всех типов, таких как дискриминационные объединения, как показано Мау, классов, записей и взаимно-рекурсивных функций.

Неограничивающий пример:

let rec foo x = bar x
and bar x = foo x

Ответ 3

Возможно, это сработает:

type IntExpression =
  ...
and BoolExpression = 
  ...

(информация взята из эта страница в MSDN.)