phaz
phaz

Reputation: 882

Recursive records in F#

A friend and I are reading up on F# and are messing around with records at the moment.

We have made the following record for representing a person:

type Person =
  {name: string;
   father: Person;
   mother: Person;}

F# Interactive accepts it, and in some way, the type makes sense, except we can't see how to use it. When we try to declare a person, we have to declare the parents at the point of declaration, and in turn declare their parents and so on. Is there any way to actually use this type? And if not, how come we are even able create it?

PS: We are well aware that since parents are intended to be optional, we should have encapsulated them with the option (Some x | None) type.

EDIT

My question is not how to fix the above, a solution is already written in the PS. My question is, can I actually use the above type, e.g. declare a Person record of the above form? If not, I must have made an unusable type. Why can I make such a type?

Upvotes: 6

Views: 1021

Answers (2)

kvb
kvb

Reputation: 55184

Lee shows a more useful definition, but you can create an instance of your Person type:

let rec loopy = { name = "loopy"; father = loopy; mother = loopy }

or

let rec male = { name = "male"; father = male; mother = female }
  and female = { name = "female"; father = male; mother = female}

Of course, these aren't at all helpful if you're modeling real people, but the compiler doesn't know that. A similar recursive type could be useful if you're trying to define a cycle, for instance.

Upvotes: 12

Lee
Lee

Reputation: 144126

If you declare father and mother as Parent option then you can use it like:

let f = { name = "Father"; father = None; mother = None }
let m = { name = "Mother"; father = None; mother = None }
let c = { name = "Child"; father = Some(f); mother = Some(m) }

without using Parent option for father and mother you would have to create a "null parent" instance and use that instead of None.

Upvotes: 9

Related Questions