Skip to content

Domain-types update

Pre-release
Pre-release
Compare
Choose a tag to compare
@louthy louthy released this 02 Sep 22:27
· 145 commits to main since this release

Domain-types are still a relatively nascent idea for v5 that I am playing around with. I wouldn't use them in anger unless you're ok with updating your code when I change them. Because I will!

Anyway, the updates are:

  • Improved documentation
  • Changed their inheritance hierarchy so don't see so many where constraints
  • DomainType<SELF, REPR> has a base DomainType<SELF>. The derived domain types (Identifier, Locus, VectorSpace, and Amount) inherit from DomainType<SELF>.
    • So, they don't need to specify a REPR type, simplifying the traits.
    • It does however mean that you will need to specify the DomainType<SELF, REPR> type as well as whatever derived domain type to gain a constructable value (see the Length example later)
  • Changed From in DomainType<SELF, REPR> to return a Fin<SELF. This allows for validation when constructing the domain-type.
    • Because this isn't always desired, you can use an explicitly implemented interface method to override it.
      • See the Length example below
  • Dropped the Quantity domain-type for now
    • I need to find a better approach with C#'s type system
public readonly record struct Length(double Value) :
    DomainType<Length, double>, //< note this is now needed, because Amount only impl DomainType<Length>
    Amount<Length, double> 
{
    public static Length From(double repr) => 
        new (repr);
    
    public double To() =>
        Value;

    // explicitly implemented `From`, so it's not part of the Length public interface
    static Fin<Length> DomainType<Length, double>.From(double repr) =>
        new Length(repr);

    public static Length operator -(Length value) => 
        new (-value.Value);

    public static Length operator +(Length left, Length right) => 
        new (left.Value + right.Value);

    public static Length operator -(Length left, Length right) => 
        new (left.Value - right.Value);

    public static Length operator *(Length left, double right) => 
        new (left.Value * right);

    public static Length operator /(Length left, double right) => 
        new (left.Value / right);

    public int CompareTo(Length other) => 
        Value.CompareTo(other.Value);

    public static bool operator >(Length left, Length right) =>
        left.CompareTo(right) > 0;

    public static bool operator >=(Length left, Length right) => 
        left.CompareTo(right) >= 0;

    public static bool operator <(Length left, Length right) => 
        left.CompareTo(right) < 0;

    public static bool operator <=(Length left, Length right) => 
        left.CompareTo(right) <= 0;
}