-
Notifications
You must be signed in to change notification settings - Fork 181
Imprecision about the identity of keys (when Eq
is not the smallest reflexive relation)
#587
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
Comments
Can you point to an example where properties of an API using But the someone will use such non-standard instances, and this will invariably lead to confusion, e.g., https://mail.haskell.org/pipermail/libraries/2018-December/029299.html (this is an instance of Hyrum's law http://www.hyrumslaw.com/ ) "update keys": in general, this would require re-balancing, while updating the value never does. Or do you want to restrict key updates to cases that don't re-balance (because the new key compares EQ to the old one)? How do you want to enforce this? (Last I checked, implementation (Data.Map) only uses |
#316 seems related. |
I've been thinking about this recently due to #1118, and I think we should address this properly. Before going further, note that
So such instances might be useful but they risk unexpected behavior from any function that expects this property to hold. The current status of The current status is unsatisfactory, and I see three options for improving it. A. Proper support for such keysThis means that we will not only have
and more. For
and so on. As you can tell, this will explode the already large APIs of B. Specify the behavior of functions on such keysSome functions already do this, this is about doing the same for the rest. For instance This option is neither here nor there. You will know exactly what happens but what happens may not be what you want. Then we might get requests to add the behavior one wants, which we won't because we are not doing option A. C. Document that the behavior on such keys is unspecified across the libraryThis is the most reasonable option to me. It keeps the library in its current scope and manageable. The few functions that specify a particular behavior today will not be changed, unless there is good reason to do so. For instance, Now it is true that such keys can be useful in practice and it is also true that the |
This issue is related to #290, #291, #52 (that one found by github Related Issues). There are situations where one would distinguish equal keys (in the sense of
Eq
) and identical keys (in the extreme pointer-identity).The following is a (unrealistic) mock scenario, but it exemplifies the point. Here
Eq
on keys is very generous:What do we expect
test
to be? What does the documentation predict?Lets read the documentation for
Map.update
!containers/Data/Map/Internal.hs
Line 1062 in f7273d1
containers/Data/Map/Internal.hs
Lines 1053 to 1055 in f7273d1
According to the documentation "... is
(Just y)
, the keyk
is bound to the new valuey
", we expect the keyk = Key 2
to be bound to"bar"
.However,
test
is:This means the documentation is imprecise (wrong is a hard word). The precise wording would be "...the existing key (which is
== k
) is bound to the new valuey
".On a more general note, the API for containers prevents the user to conveniently and efficiently inspect and update the keys of finite sets/maps. There seems to be a hidden assumption that no complex data structures are used as keys, and key equality is always uninteresting. This excludes practical scenarios where one would want to use finite maps also as managing data structure for the keys.
In case you wonder about practical scenario:
My own scenario is LALR parser generation where I maintain a map
m
from parse states (keys) to state numbers (values). A parse state is itself a map from parse items (dotted grammar rules) to lookaheads (token sets). LALR fuses parse states that only differ in the lookaheads, thus, for the sake ofm
I use an equality on parse states that ignores the lookaheads. (Eq
is(==) ``on`` keysSet
.) However, in the end I want the parse state with the largest lookaheads, thus, I need to update a key ofm
if I have a version of that key with larger lookaheads.The text was updated successfully, but these errors were encountered: