Search code examples
f#recursiondiscriminated-unionmutual-recursion

Can discriminated unions refer to each other?


I'm building an expression tree using discriminated unions. The below code:

type IntExpression =
    | TrueIsOne of BoolExpression

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

throws an error because BoolExpression is not defined. Swapping the definitions just results in the reverse (IntExpression is not defined) as you would expect.

Is there a way around this?


Solution

  • Yes, use and to group type definitions with inter-dependencies:

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