Slide 14 de 74

Result<T, E>

func half(n: Int): Result<Int, Str> {
	if n % 2 == 0 {
		return Result.Ok(n / 2)
	}
	return Result.Error("{n} não é par")
}

func describe(n: Int): Str {
	answer := half(n)
	if answer is Result.Ok(v) {
		return "metade: {v}"
	} else if answer is Result.Error(why) {
		return why
	}
}

proc main(): void {
	echo describe(4)    // metade: 2
	echo describe(5)    // 5 não é par

	if half(40) is Result.Ok(v) && v > 10 {
		echo "uma metade grande: {v}"
	}
}

Result é como toda operação falível se reporta: Result.Ok(valor) quando deu certo, Result.Error(carga) quando não deu. É a única união genérica nativa da linguagem, escrita Result<Int, Str> para um Int ou uma Str explicando por que não.

r is Result.Ok(v) é um Bool que é true quando r guarda um Ok, e vincula v ao que ele carrega para o ramo que protege, e para o resto da mesma condição depois de &&. Uma cadeia if/else if que testa um mesmo sujeito para Ok e Error cobre todos os casos, então uma função pode terminar nela sem um else morto. Um ramo que acrescenta uma condição própria, answer is Result.Ok(v) && v > 10, não cobre nada: ele pode ser falso com um Ok na mão. Os slides sobre casamento de padrões mostram tudo o mais que is sabe fazer.