When writing functions that might fail (e.g., accessing an index in a list that is too short), avoid returning a 'magic' default value like 42. Instead, use an inductive type like natoption to explicitly represent success or failure.
natoption has two constructors:
Some n: Represents a successful result containing the value n.None: Represents a failure or an empty result.
To extract a value from a natoption while providing a fallback, use an elimination pattern (like option_elim).
Inductive natoption : Type :=
| Some (n : nat)
| None.
(* Example: nth_error returns Some value if index exists, otherwise None *)
Fixpoint nth_error (l:natlist) (n:nat) : natoption :=
match l with
| nil => None
| a :: l' => match n with
| 0 => Some a
| S n' => nth_error l' n'
end
end.
(* Example: option_elim extracts the value or returns a default *)
Definition option_elim (d : nat) (o : natoption) : nat :=
match o with
| Some n' => n'
| None => d
end.