6

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?

mushroom
  • 6,201
  • 5
  • 36
  • 63
  • E.g. the Coq standard library uses `Fin` for indexing into vectors. See the definition of the `nth` function [here](https://coq.inria.fr/library/Coq.Vectors.VectorDef.html). – Anton Trunov Oct 02 '16 at 07:13

1 Answers1

4

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
Yuuri
  • 1,858
  • 1
  • 16
  • 26