type Shape {
Circle { radius: Int }
Rectangle { width: Int, height: Int }
Point
}
func area(shape: Shape): Int {
if shape is Shape.Circle(r) {
return 3 * r * r
} else if shape is Shape.Rectangle(w, h) {
return w * h
} else if shape is Shape.Point {
return 0
}
// Sem `else`, e nenhum é preciso: as três variantes são o Shape inteiro.
}
func size(found: Result<Int, Str>): Int {
if found is Result.Ok(n) {
return n
} else if found is Result.Error(_) {
return -1
}
}
proc main(): void {
echo area(Shape.Rectangle(3, 4))
echo size(Result.Error("missing"))
}type Route {
Page { segments: Str[dyn] }
Missing
}
// Todo valor que um Result<Route, Str> pode ter é aceito abaixo, então
// a cadeia encerra a função e nada precisa vir depois dela.
func kind(r: Result<Route, Str>): Str {
if r is Result.Ok(Route.Page([])) {
return "uma página vazia"
} else if r is Result.Ok(Route.Page([_, ...more])) {
return "uma página de {len(more) + 1}"
} else if r is Result.Ok(Route.Missing) {
return "uma página ausente"
} else if r is Result.Error(_) {
return "nenhuma página"
}
}
proc main(): void {
echo kind(Result.Ok(Route.Page(["a", "b"]))) // uma página de 2
echo kind(Result.Ok(Route.Missing())) // uma página ausente
echo kind(Result.Error("offline")) // nenhuma página
}Uma cadeia if/else if sem else encerra um caminho quando seus ramos aceitam todo valor do sujeito e todo ramo termina. É isso que permite escrever uma função total sobre uma união sem um else morto, e esquecer um caso é então um erro de compilação que nomeia um valor que nada aceita — `r` when it is `Result.Ok(Route.Missing)`.
O que conta para cobrir:
Result por Ok e Error, até onde os padrões descem: Result.Ok(Route.Page(_)), Result.Ok(Route.Missing) e Result.Error(_) cobrem um Result<Route, Str>;[] e [first, ...rest] aceitam todos — e um Bool por true e false;"{text}", que aceita toda string;shape is Shape.Circle(r) && r > 0, não conta para nada, já que pode não casar com todo círculo;order.status; uma chamada não é, já que pode responder diferente a cada vez.Uma cadeia que não pode ser provada como cobrindo o sujeito precisa de um último return, ou de um panic para um caso que não pode acontecer.