5

The natToFin function from the standard library has the following signature:

natToFin : Nat -> (n : Nat) -> Maybe (Fin n)

natToFin 4 5 returns Just (FS (FS (FS (FS FZ)))) : Maybe (Fin 5), while natToFin 5 5 returns Nothing.

I would like a function with the following signature:

myNatToFin : (m : Nat) -> (n : Nat) -> { auto p : n `GT` m } -> Fin n

It behaves the same as the standard lib function but doesn't need to return a Maybe because it is always possible to generate a Fin n from m given that n is greater than m.

How do I implement myNatToFin?

Cactus
  • 27,075
  • 9
  • 69
  • 149
mushroom
  • 6,201
  • 5
  • 36
  • 63

1 Answers1

5

You can do it directly by recursing on m, n, and the evidence for n `GT` m at the same time:

import Data.Fin

myNatToFin : (m : Nat) -> (n : Nat) -> {auto p : n `GT` m} -> Fin n
myNatToFin Z (S n) = FZ
myNatToFin (S m) (S n) {p = LTESucc _} = FS $ myNatToFin m n

Note that you need to pattern match on p in the second case (even though its value is not used on the right-hand side) so that the automatic argument for the recursive call can be filled in.

Cactus
  • 27,075
  • 9
  • 69
  • 149