1

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.

corazza
  • 31,222
  • 37
  • 115
  • 186

1 Answers1

3

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
xash
  • 3,702
  • 10
  • 22
  • Nice thank you again. But, before I wrote this, I wrote an index function for `VVect` with type `index : {n : Nat} -> (i : Fin n) -> (xs : VVect is t) -> Vect (index i is) t`. At first I thought it wouldn't work exactly for this reason, but it did, so I thought that scoping rules for implicit arguments were somehow different / non-intuitive, i.e. I thought data declarations somehow declared them globally as well. Do you know why that index function can be defined like that? I guess there's some inferred dependency I'm missing – corazza Sep 25 '18 at 06:44
  • 1
    Because of `index : Fin len -> Vect len elem -> elem`, Idris can figure out that the `VVect`s length is the same `n` as in `Fin n`. If you replace `index i is` with e.g. `Z`, you can see with hole inspection, that there are both `n` (from the `VVect`) and `n1` (from `{n : Nat}`). It compiles, but you won't be able to unify them. – xash Sep 25 '18 at 09:31
  • pssst hey man, wanna buy some rep? https://stackoverflow.com/questions/53570447/control-st-pure-type – corazza Dec 01 '18 at 18:45