-
Notifications
You must be signed in to change notification settings - Fork 253
Closed
Description
The current take in Data.Vec.Base is defined as:
take : ∀ m {n} → Vec A (m + n) → Vec A m
take m xs = proj₁ (splitAt m xs)
This is a useful total function, but it requires that the input vector has exactly m + n elements. While this is type-safe, it makes many natural theorems difficult or verbose to express—especially when working with partial takes on vectors of unknown or unrestricted size.
For example, the following becomes difficult, requiring rewrites and equalities just to satisfy the type of take:
take-++-more : ∀ {A : Set} {m n k : ℕ} → (xs : Vec A m) → (ys : Vec A n) → (p : ℕ) → (m≤p : m ≤ p) → (m+n≡p+k∸n : m + n ≡ p + (n ∸ k)) → (n≡k+n-k : n ≡ k + (n ∸ k)) →
toList (Data.Vec.Base.take p (cast m+n≡p+k∸n (xs Data.Vec.Base.++ ys))) ≡ toList (xs Data.Vec.Base.++ (Data.Vec.Base.take k (cast n≡k+n-k ys)))
So, maybe we could add a less restrictive version of take, named takeNat, defined as:
takeNat : ∀ {A : Set} {m : ℕ} → (k : ℕ) → Vec A m → Vec A (k ⊓ m)
takeNat zero xs = []
takeNat (suc k) [] = []
takeNat (suc k) (x ∷ xs) = x ∷ takeNat k xs
This definition behaves like List.take, and avoids the need for index coercion or auxiliary equalities.
With takeNat, the same lemma becomes:
takeNat-++-more : ∀ {A : Set} {m n : ℕ} → (xs : Vec A m) → (ys : Vec A n) → (p : ℕ) → m ≤ p
→ toList (takeNat p (xs Data.Vec.Base.++ ys)) ≡ toList (xs Data.Vec.Base.++ takeNat (p ∸ m) ys)
Feedback on this suggestion, definition, naming, and placement is welcome.
Metadata
Metadata
Assignees
Labels
No labels