Another important element in algebraic data types is the sum type, which is represented by unite
in the Valkyrie language.
unite Each variant can have its own field, or it can have no field
unite Test {
A { }
B {
b: int
}
C {
c1: int
c2: str
}
}
Unite can easily use pattern matching to implement interfaces
extends Test {
to_string(self) {
self.match {
case A: "A"
case B(b): "B: integer is {b}"
case C(c1, c2): "C: integer is {c1}, string is {c2}"
}
}
}
Implementation Details
Disjoint union types will be expanded to trait
+ subtype
.
unite Result<T, E> {
Success {
value: T
}
Failure {
error: E
}
}
extends Result<T, E> {
unwrap(self) -> T / E {
match self {
Success(value) => value
Failure(error) => raise error
}
}
}
You can also manually implement an extensible Σ type based on this.
@unite
@implements.in(file)
trait Result<T, E> {
unwrap(self): T / E
}
@variant
class Success<T, E>: Result<T, E> {
value: T
construct(value: T) {
self.value = value
}
extract(self) -> [value: T]? {
Some([self.value])
}
unwrap(self) -> T {
self.value
}
}
@variant
class Failure<T, E>: Result<T, E> {
error: E
construct(error: E) {
self.error = error
}
extract(self) -> [error: E]? {
Some([self.error])
}
unwrap(self) / E {
raise self.error
}
}
Note that the construct
and extract
here are not written in the trait constraints, so that subclasses can implement them according to their needs