3 ms·
I think that is highly questionable. Sum Types are a different approach with some advantages and some disadvantages over inheritance. Nothing more and nothing l
by thomasz 11y ago
I think that is highly questionable. Sum Types are a different approach with some advantages and some disadvantages over inheritance. Nothing more and nothing less. They really shine if you have clearly defined types that seldom change. On the other hand, discriminated unions make it absurdly complicated to defend against some errors that are almost comically easy to avoid by using a standard OO approach:
class Range {
public int From {get;}
public int To {get;}
public Range(int from, int to) {
Assert(from <= to);
From = from; To = to;
}
}
- kvb 11y agoYour particular example doesn't seem especially object oriented (e.g. it looks like a simple data type with a "smart constructor", which is a common pattern in, say, Haskell, too). But in any case F# supports both discriminated unions as well as normal OO design, while C# supports only the latter, so in that subset of cases that are better modeled by DUs F# will be strictly better, and in the rest of the cases it won't be worse.
- thoth 11y agoNobody says you have to use sum types to solve all problems in the design domain - and as kvb points out, F# does have OO functionality too. Your proposed problem might be better solved with the Option type and a simple guard to return None if out of range. >comically easy to avoid using a standard OO approach This is an ironic statement given that your code, as written, is circumvented by subclassing Range and side-stepping its constructor. I suppose you actually meant "sealed class"... but we're getting off in the weeds again, missing the fundamental point of the post.
- thomasz 11y ago> This is an ironic statement given that your code, as written, is circumvented by subclassing Range and side-stepping its constructor. You are the second one who says this. I must admit that I do not understand how this would be possible. The properties are not virtual, and not writable for anything but the base constructor. To my knowledge, it's impossible avoid the base classes constructor by subclassing. I'm pretty sure you can actually circumvent the assert, but you would have to use the heavy weapons in the reflection API. class Range { public int From { get; } public int To { get; } public Range(int from, int to) { Assert(from <= to); From = from; To = to; } } class LolRange : Range { public LolRange() : base(0,1) { From = 1; To = 0; } } Error CS0200 Property or indexer 'Program.Range.From' cannot be assigned to -- it is read only Error CS0200 Property or indexer 'Program.Range.To' cannot be assigned to -- it is read only