-
Notifications
You must be signed in to change notification settings - Fork 242
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
a better scanr
, via Data.List.NonEmpty
#2258
Conversation
Shouldn't the |
@gallais wrote:
I don't think so, although perhaps you could argue either way. I think the main point is that
That's more plausible, but then where does its defining property All that said (and done): |
Thanks @JacquesCarette for the feedback. Any suggestions as to how to "find the way out of the bottle"? UPDATED: hopefully the latest revisions are now more inline with your review comments! |
-- definition | ||
|
||
scanr : List A → List B | ||
scanr = toList ∘ scanr⁺ f e |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is screaming to me that we're doing something wrong here with the dependencies. Can we discuss this evening at the stdlib implementor's meeting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, this is the motor for this PR: AFAICT, the Data.List.Base
defn of scanr
arises in the (historical) form it takes precisely to ensure that it can exist in Data.List.Base
, without any of the other analysis of its typing.
But, as other commenters elsewhere note, the 'official' library definition has terrible properties (or better: terrible proofs of its properties...) because of its 'wrinkly' definition, arising from its combination of with
and dead-code.
The other operations considered in #2267 / #2269 are OK, but scanr
seems 'special'.
This PR represents my attempt at the least-invasive restructuring of Data.List.Base
able to avoid the wrinkles...
So I think we've (now) agreed to find a better home for this (and #2269 ) under |
Aaargh: |
So I think that the stuff in #2269 doesn't really need to move? At least, I don't immediately see the need. So that leaves just Or do |
Well, good question...
So, I could imagine that #2269 is 'redundant'/'invalid', but for the fact that taken all together, the four functions belong with one another. It's a judgment call (and one which |
An alternative, but for the cost of a horrible allocation overhead (because we can't write functions putting multiple return values on the stack!) against a benefit of being observably scanr : (A → B → B) → B → List A → List B
scanr {A = A} {B = B} f e xs = let h , t = go xs in h ∷ t
where
go : List A → B × List B
go [] = e , []
go (x ∷ xs) with y , ys ← go xs = f x y , y ∷ ys |
That version of |
Thanks @Taneb ! Sorry my recent preoccupations have meant this PR got ignored/abandoned for a while. If there were general assent towards |
I'm a huge believer in "follow the elegant path". Not always (there's lots of room for solid engineering and usability to disrupt some elegant paths), but whenever realistic. I sometimes say it as "follow the math", but by this I usually mean "the simple definitions, without unexplained / unexplainable detours". Those anomalies are a signal, and they're the kinds of signals that I love to pursue. |
If we agree to move this to |
Now see #2395 |
Avoids the
with
-based definition in favour of a simpler definition using (pattern-matching ;-))let
, with no dead-code branch... cf. also #1937 , #2123