untagged union types #1

Open
alexander.nutz wants to merge 1 commits from proposal/untagged-unions into main
Showing only changes of commit 34fd8fa0a0 - Show all commits

27
spec.md
View File

@@ -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