Can discriminated unions refer to each other?
Asked Answered
B

3

14

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?

Burushaski answered 22/7, 2010 at 12:43 Comment(2)
possible duplicate of F# forward type declarationsMountain
@Mountain It is the same question, but the terminology is different enough that I failed to find it with either Google or the site search. That alone might be a reason to leave both open.Burushaski
O
23

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
Oogenesis answered 22/7, 2010 at 12:47 Comment(0)
G
9

"and" works generally for types with mutual dependencies. That is, it works for all types, such as discriminated unions, as shown by Mau, classes, records and mutually recursive functions.

Non terminating example:

let rec foo x = bar x
and bar x = foo x
Gilbart answered 22/7, 2010 at 13:35 Comment(0)
G
4

Perhaps this will work:

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

(Information taken from this page on MSDN.)

Glabrescent answered 22/7, 2010 at 12:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.