Skip to content

Data.Vec.Base.splitAt, take and drop green slime #2057

@JacquesCarette

Description

@JacquesCarette

The "improved" implementation of PR #2056 still is flawed. For ease of comparison, it is

splitAt :  m {n} (xs : Vec A (m + n)) 
          ∃₂ λ (ys : Vec A m) (zs : Vec A n)  xs ≡ ys ++ zs
splitAt zero    xs                = ([] , xs , refl)
splitAt (suc m) (x ∷ xs)          with splitAt m xs
splitAt (suc m) (x ∷ .(ys ++ zs)) | (ys , zs , refl) =
  ((x ∷ ys) , zs , refl)

But this says: if you give me (splitAt) a Vec xs that you built in such a way that you know that its length is of the form m + n, then I can split it into two pieces which will concatenate to the original, with the pieces being of the 'right' length.

It's pretty much sure that the vector that you want to split wasn't actually built that way! To me, a better interface (and code) should be:

splitAt :  m {n o}  (o≡m+n : o ≡ m + n)  (xs : Vec A o) 
          ∃₂ λ (ys : Vec A m) (zs : Vec A n)  cast o≡m+n xs ≡ ys ++ zs
splitAt zero    p xs                = ([] , cast p xs , refl)
splitAt (suc m) p (x ∷ xs)          with splitAt m (suc-injective p) xs
splitAt (suc m) p (x ∷ xs) | (ys , zs , p′) = ((x ∷ ys) , zs , cong (x ∷_) p′)

But that is quite a large interface change. It does get rid of the green slime. [And I'm annoyed there's a need for cast but that might be inevitable.]

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions