I'd like to have a Nat
that remains within a fixed range. I would like functions incr
and decr
that fail if they are going to push the number outside the range. This seems like it might be a good use case for Fin
, but I'm not really sure how to make it work. The type signatures might look something like this:
- Returns the next value in the ordered finite set.
- Returns Nothing if the input element is the last element in the set.
incr : Fin n -> Maybe (Fin n)
- Returns the previous value in the ordered finite set.
- Returns Nothing if the input element is the first element in the set.
decr : Fin n -> Maybe (Fin n)
The Nat
will be used to index into a Vect n
. How can I implement incr
and decr
? Is Fin
even the right choice for this?
I guess the easiest way is to use some standard Fin↔Nat conversion functions from Data.Fin
:
incr, decr : {n : Nat} -> Fin n -> Maybe (Fin n)
incr {n=n} f = natToFin (succ $ finToNat f) n
decr {n=n} f = case finToNat f of
Z => Nothing
S k => natToFin k n