F# sum type with recursion?

Viewed 112

I'm trying to define a type with a constructor which receives a sum type of itself or another type. But because I must define the sum type separately, either the sum type or one of the types used in the sum type are undefined at the point of the constructor.

module BasicFunctions =

type Type1() = 
    class end

type Type1OrType2 = T1 of Type1 | T2 of Type2 // Type2 not yet defined

type Type2(x: Type1OrType2) = // Same thing for Type1OrType2 if Type1OrType2 is placed below Type2
    class end

In Scala (for example), I can define a sum type inline, such that one of the types in the sum type is the type being defined itself:

case class Type1()

case class Type2(x: Type1 | Type2)

@main def Main() =
  val t1 = Type1()
  val t2 = Type2(t1)
  val t3 = Type2(t2)

Is there a way to make an "inline" definition of a sum type of this kind in F#, thus taking advantage of recursion?

2 Answers

You can do this by using the type ... and syntax, which lets you define a group of mutually recursive type definitions:

type Type1() = 
    class end

type Type1OrType2 = T1 of Type1 | T2 of Type2

and Type2(x: Type1OrType2) = 
    class end

Another approach is to make the module recursive:

module rec BasicFunctions =

    type Type1() = 
        class end

    type Type1OrType2 = T1 of Type1 | T2 of Type2 // Type2 not yet defined

    type Type2(x: Type1OrType2) = // Same thing for Type1OrType2 if Type1OrType2 is placed below Type2
        class end
Related