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:
How does this translate to F#? Use classes, records, union types?
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. Thanks.
If there is already an article about that topic please point me to it as well. I might have missed it.
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!
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.