I'm trying to define the dependent type of n-ary functions (built as a tree out of binary and unary functions; I suspect this is isomorphic to the type of (Vect n a) -> a
) as an exercise in learning Idris.
While trying to define a function that applies an argument to an n-ary function (producing an (n-1)-ary function) I got a very suspicious error:
Type mismatch between
ArityFn m a (Type of ng)
and
ArityFn (minus m 0) a (Expected type)
Specifically:
Type mismatch between
m
and
minus m 0
here's the code in question, for reference
data ArityFn : Nat -> (ty: Type) -> Type where
Val : (x : ty) -> ArityFn 0 ty
UnaryFn : (ty -> ty) -> ArityFn 1 ty
BinaryFn : (ty -> ty -> ty) -> ArityFn 2 ty
NAryFn : (ty -> ty -> ty) -> (ArityFn n ty) -> (ArityFn m ty) -> ArityFn (n + m) ty
%name ArityFn nf, ng, nh
applyArityFn : a -> (ArityFn n a) -> (LTE 1 n) -> ArityFn (n - 1) a
... (some definitions elided)
applyArityFn x (NAryFn h (UnaryFn f) ng) _ = mkNAryFn h (Val (f x)) ng
is this a bug in the typechecker?
When in doubt, look for the definition of the function which got stuck:
:def minus
returns (among other things, modulo some cleanup):
Original definiton:
minus 0 right = 0
minus left 0 = left
minus (S left) (S right) = minus left right
You can see that minus left 0 = left
won't hold definitionally because there is a pattern minus 0 right = 0
before. Now, of course both equations return the same result when they happen to coincide but idris doesn't know that.
To get the result you want you can:
m
and get minus
to reduce now that the head constructor of its first argument is exposedminus m 0 = m
.