4 ms·
So, yes, one can view SQL as one of these languages that has trouble with sum types and a faithful representation of a tagged sum in SQL is Either Supplier
by crdrost 3y ago
So, yes, one can view SQL as one of these languages that has trouble with sum types and a faithful representation of a tagged sum in SQL is
Either Supplier Agency
<-->
CREATE TABLE supplier_or_agency (
id UUID PRIMARY KEY,
supplier_id UUID,
agency_id UUID
);
ALTER TABLE supplier_or_agency
ADD CONSTRAINT only_one_null
CHECK (
CASE WHEN supplier_id IS NULL
THEN agency_id IS NOT NULL
ELSE agency_id IS NULL
END);
And this sort of convention can be carried over to Java, where after all these are just pointers...
class SupplierOrAgency {
private final Supplier supplier;
private final Agency agency;
private SupplierOrAgency(Supplier s, Agency a) {
supplier = s;
agency = a;
}
public static of(@NonNull Supplier s) {
return new SupplierOrAgency(s, null);
}
public static of(@NonNull Agency a) {
return new SupplierOrAgency(null, a);
}
// Add getters and maybe an enum I guess?
}
And yes then you get an approach like that.
The basic problem for interpretability is that you get annoying questions about "what if the API that I am consuming violates their contract” or maybe even “TypeScript can't figure out that because these two are null it must be that that one is not null” or some similar crap.
The truth is, in SQL databases this never comes up. So the only reason that you are doing this is that you want to have a collection that contains both data types, and in SQL such a collection is a record that exists in some table, membership in that collection is by other things pointing at the collection. This makes it effortless to just have two collections on the same record, one of agencies and one of suppliers.
Similarly in Java, instead of
public Foo {
@NonNull public List<SupplierOrAgency> resources;
}
It makes more sense from a type safety perspective to just have two collections,
public Foo {
@NonNull public List<Supplier> suppliers;
@NonNull public List<Agency> agencies;
}