
Malcolm Wallace wrote:
Here is a strawman proposal, which does not fix the consecutive update problem, but which might address the original typing problem.
I think it does not really address the original typing problem. It would allow you to write:
voidcast v@(VariantWithTwo{}) = v { field1 = Void , field2 = Void } voidcast v@(VariantWithOne{}) = v { field1 = Void , field2 = Void }
Setting field2 only assures type correctness, but the value of field2 would be ignored at runtime. I'ld rather define an empty polymorphic element and update that one: e = VariantWithOne { field1 = undefined } voidcast VariantWithOne{} = e { field1 = Void } In the last line e is (only) instantiated (and not casted).
The Report (section 3.15) defines the following conditions on a named field update:
* all labels must be taken from the same datatype * at least one constructor must define all of the labels mentioned in the update * no label may be mentioned more than once * an execution error occurs when the value being updated does not contain all of the specified labels.
Now, this last condition is rather nasty - a runtime error - and I would like to eliminate it. I think we can do so by also eliminating the second condition. That is, I would like to be able to use a set of labels that might not be contained solely within a single constructor. The obvious semantics is that if a constructed value does not contain a label of that type, that part of the update is discarded. Hence, I could write a single expression that updated all possible variants of a type, simply by unioning all their possible labels.
I want to detect errors as early as possible. Christian