F# Choice to C#

April 17, 2025    F# C# Development

Using Github Copilot to Convert F# Choice to C#

We were curious what Github Copilot would do with a simple F# choice statement. We wanted to see if it could convert it to C#. The F# code is as follows:

type Contact = {
  ContactId: ContactId
  Info: ContactInfo
}
and ContactInfo = 
  | Email of EmailAddress
  | Phone of PhoneNumber
and EmailAddress = EmailAddress of string
and PhoneNumber = PhoneNumber of string
and ContactId = ContactId of string

“convert this to C#” was the prompt we used. The result was:

public class Contact
{
  public ContactId ContactId { get; set; }
  public ContactInfo Info { get; set; }
}

public abstract class ContactInfo { }

public class Email : ContactInfo
{
  public EmailAddress EmailAddress { get; set; }
}

public class Phone : ContactInfo
{
  public PhoneNumber PhoneNumber { get; set; }
}

public class EmailAddress
{
  public string Value { get; }

  public EmailAddress(string value)
  {
    Value = value;
  }
}

public class PhoneNumber
{
  public string Value { get; }

  public PhoneNumber(string value)
  {
    Value = value;
  }
}

public class ContactId
{
  public string Value { get; }

  public ContactId(string value)
  {
    Value = value;
  }
}

That is very verbose and we want to keep the immutable approach.

I then asked Copilot “convert this to C# with records”. The result was:

public record Contact(ContactId ContactId, ContactInfo Info);

public abstract record ContactInfo;
public record Email(EmailAddress emailAddress) : ContactInfo;
public record Phone(PhoneNumber phoneNumber) : ContactInfo;

public record EmailAddress(string value);
public record PhoneNumber(string value);
public record ContactId(string value);

That looks much better. It’s interesting to see how an abstract record can be used for a Choice Option type in F#.

I’m happy with how Github Copilot is helping me learn F#. It’s also making the decision on what language to a lot less weighty.