-
Notifications
You must be signed in to change notification settings - Fork 246
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Data.Vec.Base.splitAt
, take
and drop
green slime
#2057
Comments
It might be more consistent with elsewhere to express the equalities the other way around, so we transform the more complicated expression into the simpler one (and expect the equality that way around for the addition equality) |
I don't think it's appropriate to call it 'green slime': it's a view so its whole purpose The proposed changes give you back a |
@Taneb that was my instinct as well, but then all the @gallais of course I'm not calling Now, you will surely have also noticed that while I submitted the previous as a PR, this is an issue. I knew this one would need non-trivial discussion and ran a real risk of rejection (that In the end, what you say at the end is probably the "route forward": in common use, calls to |
I don't think it's necessarily true that we arrived there by using concat. We could for instance be working with a vector of size I see the current
And I don't think we should change all of the |
My ignorant question: why do we want to return the proof that the resulting vecs append to create the original one in the function? Wouldn't it be more normal to have that as a property in |
Nothing ignorant about such a question at all! Indeed, I'm ignorant as to the particular history of A 2001/2004-era McBride&McKinna ( data View {m} {n} : Vec A (m + n) → Set where
split : (xs : Vec A m) → (ys : Vec A n) → View (xs ++ ys) with Time goes by... greater awareness of/sensitivity towards equality... observational type theory... greater awareness of/sensitivity towards 'green slime'... data View {m} {n} (zs : Vec A (m + n)) : Set where
split : (xs : Vec A m) → (ys : Vec A n) → zs ≡ xs ++ ys → View zs Now, the The last design/refinement/refactoring step (in the case of As to "more normal", that's a particular choice in the current stdlib design, and as elsewhere, I would still, 20+ years on, wish to argue for view-based programming as an important part of "why dependent types matter" in programming... but, again as ever, YMMV (and, to date, has so varied;-)). |
TL;DR: if you want to invert a function, and you want that inverse operation to be 'correct-by-definition', then (implicitly or explicitly) there's an equation to prove (cf
We tried to argue in 2004 (successfully or otherwise) that the latter approach was the 21st century way to go about things (and was, in fact, already known in the 20th century, but not effectively operationalised until ... 'proper' implementations of dependent type theory started to come along). For a recent instantiation of the ideas, see #1923 and the discussion of use of the view there to invert |
Ob: directions of equations, and the ambient stdlib design heuristic I think it's important to pay attention to the mode of the rewrite rule, and in particular, when the (That also correlates with 'fording' being a special instance, for the equality relation, of right Kan extension of a predicate along a relation... for those with the correct spectacles on. ) |
As a last thought on this for the time being: 'green slime' is not always easy to remove. Eg, in #2056 and the downstream issue #2090, any attempt to remove green slime from the type lookup-take : (xs : Vec A (m + n)) (i : Fin m) (m≤m+n : m ≤ m + n) →
lookup (take m xs) i ≡ lookup xs (Fin.inject≤ i m≤m+n) of Correspondingly, if the solution @JacquesCarette seeks is to remove green slime from the type of |
@JacquesCarette are you (still) keen to keep this issue open? |
Yes, I still would like to keep this open. I will want to come back to it, when I have a bit of time to breathe. Stupid admin job. |
Half a year on since the 'last' word, and a year after opening the issue... any more thoughts on this, @JacquesCarette ? |
Pondering on this again: what if the view were data View {o} (m : Fin o) (zs : Vec A o) : Set where
split : {n} (xs : Vec A (Fin.toℕ m)) → (ys : Vec A n) → zs ≡ xs ++ ys → View zs It makes sense to split a Vector at an index which we know is in the right range. And since raw numbers are a 'bad smell' in this setting, we shouldn't ask for that but a |
So... cleaning up your definition above to regularise the data View {n} (i : Fin n) (zs : Vec A n) : Set _ where
splitAt⁻¹ : ∀ {m} (xs : Vec A (Fin.toℕ i)) → (ys : Vec A m) → zs ≡ xs ++ ys → View i zs Then... toℕ i + _n_3548 != n of type ℕ
when checking that the inferred type of an application
Vec A (toℕ i + _n_3548)
matches the expected type
Vec A n with It seems as though, in order to write a |
Had an insight earlier. This encourages me to take my port of Conor's partition code and try to make it stdlib ready. |
That sounds a definite contribution! Looking forward to seeing it when it lands... |
The "improved" implementation of PR #2056 still is flawed. For ease of comparison, it is
But this says: if you give me (
splitAt
) aVec
xs
that you built in such a way that you know that its length is of the formm + 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:
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.]The text was updated successfully, but these errors were encountered: