Search code examples
idris

Trying to bring implicit argument into scope on the left side of a definition in Idris results in "is f applied to too many arguments" error


The function applyRule is supposed to extract the implicit argument n that is used in another arguments it gets, of type VVect.

data IVect : Vect n ix -> (ix -> Type) -> Type where -- n is here
  Nil  : IVect Nil b
  (::) : b i -> IVect is b -> IVect (i :: is) b

VVect : Vect n Nat -> Type -> Type -- also here
VVect is a = IVect is (flip Vect a)

-- just for completeness
data Expression = Sigma Nat Expression

applyRule : (signals : VVect is Double) ->
            (params : List Double) ->
            (sigmas : List Double) ->
            (rule : Expression) ->
            Double

applyRule {n} signals params sigmas (Sigma k expr1) = cast n

Without referring to {n}, the code type-checks (if cast n is changed to some valid double). Adding it in, however, results in the following error:

When checking left hand side of applyRule:
Type mismatch between
        Double (Type of applyRule signals params sigmas rule)
and
        _ -> _ (Is applyRule signals
                             params
                             sigmas
                             rule applied to too many arguments?)

This doesn't seem to make sense to me, because I'm not pattern-matching on any parameter that could have a dependency on n, so I thought that simply putting it in curly braces would bring it into scope.


Solution

  • You can only bring n into scope if it is defined somewhere (e.g. as a variable in the arguments). Otherwise it would be hard to figure out where the n comes from – at least for a human.

    applyRule : {is : Vect n Nat} ->
                (signals : VVect is Double) ->
                (params : List Double) ->
                (sigmas : List Double) ->
                (rule : Expression) ->
                Double
    applyRule {n} signals params sigmas (Sigma k expr1) = cast n