untagged union types #1
27
spec.md
27
spec.md
@@ -14,7 +14,9 @@
|
|||||||
One of:
|
One of:
|
||||||
- `t -> t`: pure function taking `t` as argument, and returning `t`
|
- `t -> t`: pure function taking `t` as argument, and returning `t`
|
||||||
- `{ field1: xt, field2: yt }`: non-nominal records
|
- `{ field1: xt, field2: yt }`: non-nominal records
|
||||||
- `'Case1 t | 'Case2 t2 | 'Case3 t3`: tagged unions
|
- `'MyTag t`: tagged type. If `t` is already tagged, the old tag will be overwritten!
|
||||||
|
The type can be omitted, defaulting to `Unit`: `'Example` is identical to `Example Unit`
|
||||||
|
- `t | t2 | t3`: un-tagged unions
|
||||||
- `with myGenericName: x`: introduce "generic" type `myGenericName`, which can be used in type `x`
|
- `with myGenericName: x`: introduce "generic" type `myGenericName`, which can be used in type `x`
|
||||||
- `&a 'EOL | 'Cons {v: t, next: a}`: [recursive type](##recursive-types)
|
- `&a 'EOL | 'Cons {v: t, next: a}`: [recursive type](##recursive-types)
|
||||||
- `?Identifier`: the partial type `Identifier`
|
- `?Identifier`: the partial type `Identifier`
|
||||||
@@ -56,7 +58,7 @@ type Illegal2 = &a {x: a, y: Int8}
|
|||||||
|
|
||||||
The definition of "infinite size" is:
|
The definition of "infinite size" is:
|
||||||
- for records: if _any_ of the field types has "infinite size"
|
- for records: if _any_ of the field types has "infinite size"
|
||||||
- for unions: if _all_ of the cases has "infinite size"
|
- for unions: if _all_ of the cases have "infinite size"
|
||||||
- for functions: never
|
- for functions: never
|
||||||
- for recursive types:
|
- for recursive types:
|
||||||
- if the type was already visited: yes
|
- if the type was already visited: yes
|
||||||
@@ -111,9 +113,10 @@ extend Plan with 'WritelnPlan Unit
|
|||||||
Check if type is compatible-with / assignable-to type requirements.
|
Check if type is compatible-with / assignable-to type requirements.
|
||||||
|
|
||||||
- a type is compatible with itself ofcourse
|
- a type is compatible with itself ofcourse
|
||||||
- a tagged union is compatible with anothr,
|
- a (un-tagged) union is compatible with anothr,
|
||||||
if the other one contains at least all cases from this union,
|
if the other one contains at least all cases from this union,
|
||||||
and those cases are compatible
|
determined by weather or not thos are compatible
|
||||||
|
- a `'Tag t` is compatible with `t`, or `'Tag t`, but NOT `'OtherTag t`
|
||||||
- a non-nominal record is compatbile with anohter,
|
- a non-nominal record is compatbile with anohter,
|
||||||
if the other one contains a _subset_ of the fields of this one,
|
if the other one contains a _subset_ of the fields of this one,
|
||||||
and the field types are comptible.
|
and the field types are comptible.
|
||||||
@@ -129,19 +132,9 @@ TODO: need more details?
|
|||||||
This process is performed on the resulting types of two merging branches
|
This process is performed on the resulting types of two merging branches
|
||||||
|
|
||||||
Tries, in order:
|
Tries, in order:
|
||||||
- if one of the types is a tagged union,
|
- if one of them is `'Tag a`, and the other is `b` (tagless!), will unify to `'Tag PHI(a,b)`
|
||||||
which contains only one case with an identical type,
|
- if one of them is a union, and the other one is a `t`,
|
||||||
and the other is not a tagged union,
|
it will first try for each case to unify `t` with the case, and otherwise create a new case of `t`
|
||||||
it will "attach" that case onto the other type, like this:
|
|
||||||
`'N Num | 'I Int` and `Num` -> `'N Num | 'I Int`
|
|
||||||
- if one of the types is a tagged union with exactly one case,
|
|
||||||
and the other one is not an union,
|
|
||||||
it will put that tag onto it, and phi-merge the inner types.
|
|
||||||
example: `'N Num` and `Num` -> `'N Num`
|
|
||||||
- if both types are tagged unions,
|
|
||||||
the result is an tagged union contain the csaes of both tagged unions.
|
|
||||||
union cases that are in both branches, will have their types phi-unified too.
|
|
||||||
example: `'Ok ('N Num | 'I Int) | 'SomeErr` and `'Ok Num | 'AnotherErr` -> `'Ok ('N Num) | 'SomeErr | 'AnotherErr`
|
|
||||||
- if both types are non-nominal records,
|
- if both types are non-nominal records,
|
||||||
the result will contain only fields that are present in both types.
|
the result will contain only fields that are present in both types.
|
||||||
The types of the fields will get phi-unified too
|
The types of the fields will get phi-unified too
|
||||||
|
Reference in New Issue
Block a user