How to convert base class inheritance approach into f# way

Hi all

Can anyone please point me in the right direction ?
I have something like this. That is some c# pseudo code, just to demonstrate the problem. It wont compile. A base class and some children classes. Some childs just inherit the base class, some change it.

My questions are now:

  1. How does this translate to F#? Use classes, records, union types?

  2. how can i get rid of the boolean and implement it in a better way => better domain modelling

    public class containerbase {
    public int Prop1 { get; set; }
    public DateTime Prop2 { get; set; }
    public string Prop3 { get; set; }
    public virtual bool IsActive {get; set }
    }

    // differs in properties and calculation of IsActive
    class containervariety1 : containerbase {
    public DateTime SomeTime { get; set; }
    public override bool IsActive => SomeTime > DateTime.Now
    }

    // just to have a different meaning
    class containervariety2 : containerbase {
    }

    // just to have a different meaning
    class containervariety3 : containerbase {
    }

F#

type Prop1 = Prop1 of int
type Prop3 = Prop3 of string

// how to implement the boolean
type containerbase =
        { Prop1 : Prop1 
          Prop2: DateTime option
          Prop3: Prop3 
        }

// how to implement the deviations from the containerbase???
type container =
        | containervariety1 of containerbase 
        | containervariety1 of containerbase 
        | containervariety1 of containerbase 

type containers = container list

In the end i will have a list of containers of any type end have to determine if the container is active or not active. Depending on the state there are different actions triggered.

I hope i got my question across and looking forward to some help for beginners. :slight_smile: Thanks.

If there is already an article about that topic please point me to it as well. I might have missed it.

Welcome to the forum :slight_smile:

It doesn’t look like you’re trying to port some C# code but rather that you’re trying to understand the F# way of doing things.

Therefore my first recommendation is to not think of the model in terms of C# and then translate it to F#. Instead, forget anything you know about C# (and similar languages) for now.

Think of the model as data definitions where you can use both “AND” (records) and “OR” (unions), and inheritance and overrides are not available. We are only defining the shape of the data for now, not the implementation of any code. Your example is too abstract to explain this so I’ll make up another one:

A customer has a name AND a contact method, which is either an address OR a phone number. An address has 2 lines and a postcode.

These type definitions model this domain:

type Address =
    { Line1 : string
      Line2 : string
      PostCode : string }

type ContactMethod =
    | PhoneNumber of string
    | Address of Address

type Customer =
    { Name : string
      ContactMethod : ContactMethod }

Now, what if some code needs to behave differently for the different contact methods? You can write a function which uses pattern matching on the union type:

let isContactMethodValid contactMethod =
    match contactMethod with
    | PhoneNumber phoneNumber -> isPhoneNumberValid phoneNumber
    | Address address -> isAddressValid address

In my opinion, these fundamental parts of F# are inherently simpler than the comparable parts of C#, so it’s easier to learn them from scratch rather than trying to translate your understanding of the problem from C#. Of course, understanding the relationship between the two ways of doing can still be valuable, especially if you are porting code between the languages. I hope that answers your question!

Thanks Prash

This did help me a lot.
I ended up creating the types as described and added a member method for each type called Is active to calculate the state. The state is calculated differently for each type.

1 Like