3

In Idris, if I want to remove an element based on predicate, there is filter, dropWhile, takeWhile. However, all these functions return a dependent pair (n : Nat ** Vect n elem).

Is there any function that return back as a Vect type?

For what I could think of:

  1. Convert a dependent pair to Vect

  2. Implement a type that indicate the length vector after transformation (thought I have no idea how), like Here, There

For above ideas, it seems quite cumbersome for 1 (convert every result) or 2 (design each of the type to indicate the result vector length).

Are there any better ways to achieve such behaviour?

dropElem : String -> Vect n String -> Vect ?resultLen String

gostriderful
  • 99
  • 1
  • 7

1 Answers1

1

Maybe this is what you are searching for?

import Data.Vect

count: (ty -> Bool) -> Vect n ty -> Nat
count f [] = 0
count f (x::xs) with (f x)
    | False = count f xs
    | True = 1 + count f xs

%hint
countLemma: {v: Vect n ty} -> count f v `LTE` n
countLemma {v=[]} = LTEZero
countLemma {v=x::xs} {f} with (f x)
    | False = lteSuccRight countLemma
    | True = LTESucc countLemma

filter: (f: ty -> Bool) -> (v: Vect n ty) -> Vect (count f v) ty
filter f [] = []
filter f (x::xs) with (f x)
    | False = filter f xs
    | True = x::filter f xs

Then you con do this:

dropElem: (s: String) -> (v: Vect n String) -> Vect (count ((/=) s) v) String
dropElem s = filter ((/=) s)

You can even reuse the existing filter implementation:

count: (ty -> Bool) -> Vect n ty -> Nat
count f v = fst $ filter f v

filter: (f: ty -> Bool) -> (v: Vect n ty) -> Vect (count f v) ty
filter f v = snd $ filter f v
Gregg54654
  • 150
  • 8
  • I realized that `countLemma` isn't needed. I leave it there because it may be useful elsewhere. If https://stackoverflow.com/questions/46528291/can-idris-infer-indices-in-types-of-top-level-constants gets answered positively, it gets easier to write down the result type. – Gregg54654 Oct 03 '17 at 01:15
  • So the idea is to pre-calculate the result `vect` length, therefore it passes the type checker? – gostriderful Oct 03 '17 at 06:31
  • Yes, because that's what the hole `?resultLen` in your example stands for: The length of the resulting vector and you have to know it, to write it down. If the resulting vector length gets to complicated to track, you have multiple options, depending on your use case. You could use `List` which doesen't track the length at all or some custom data type, that tracks only the property, that you need to know. For example an upper bound for the length. – Gregg54654 Oct 03 '17 at 10:49
  • Thank for the example, I'd never thought of `view` could be used in such way. – gostriderful Oct 03 '17 at 13:53