0

I'm experimenting with Idris and I had the idea to create a type that represented a valid reference to a subdivision of an array.

So for example, if the array has a size of 100 and I want my subdivisions to be of size 20, the type would ensure that you could not construct a value that referred to subdivision number 7. Here is what I came up with:

data Loc : Nat -> Nat -> Type where
  MkLoc
    :  (t : Nat)
    -> (p : Nat)
    -> {auto pNZ : NonZero p}
    -> {auto tGTEp : t `GTE` p}
    -> (i : Fin (divCeilNZ t p pNZ))
    -> Loc t p

But when I try to construct a value of this type I get an error:

Main> MkLoc 100 20 0
Error: Can't find an implementation for So (with block in integerLessThanNat 0 False (divCeilNZ 100 20 SIsNonZero)).

I tried something even simpler and still got an error:

Main> the (Fin $ divCeilNZ 100 20 SIsNonZero) 0
Error: Can't find an implementation for So (with block in integerLessThanNat 0 False (divCeilNZ 100 20 SIsNonZero)).

I don't totally understand the error message. It seems like the compiler can't prove that 0 is of type Fin (divCeilNZ t p pNZ). But why not? If divCeilNZ is total shouldn't it get computed at compile-time?

How can I get this to work?

Bryan
  • 193
  • 7

0 Answers0