-
Notifications
You must be signed in to change notification settings - Fork 36
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
Dealing with objects whose constructor is not Object
#40
Comments
This partially addresses issue #40.
This partially addresses issue #40.
This partially addresses issue #40.
I've been thinking about this a further while working on PR #41 and an alternative approach came to mind. I think that the current behaviour of prop and index lenses is reasonable. However, it might be better to "relax" their behaviour. Currently prop lenses require an The downside of a more relaxed In cases where the constructors of objects must be preserved upon construction, one could then precompose the prop with something like Similar relaxation could be useful for index lenses as well, allowing an index lens to access array like objects and then construct an const isNat = x => Number.isInteger(x) && 0 <= x
const seemsArrayLike = x => x instanceof Object && isNat(x.length) would be reasonable. The main advantage of this arrangement, more relaxed prop and index lenses, is that property and index access of, respectively, non- |
The approach of relaxing the type predicates of property and index lenses has basically now been implemented in PR #42. The first part of the approach is that property lenses are changed to accept just about any Frankly, I find this a bit scary, but I nevertheless believe it will work out nicely. The reason why I believe that the relaxed type predicates will likely be usually sufficient is that one usually uses optics to target very specific elements of data structures. The focus of a property lens is most likely either The second part of the approach is that despite the relaxed input, the outputs of property and index lenses are not changed. A property lens always produces an |
Here are few random examples on manipulating non- Property lenses can indeed access properties of pretty much any object: L.get("length", ["a","b"])
// 2 And the results are not always what one might naïvely think, but they are consistent: L.set("length", 1, ["a","b"])
// { '0': 'a', '1': 'b', length: 1 } More interestingly though, objects with non- function XYZ(x,y,z) {
this.x = x
this.y = y
this.z = z
}
XYZ.prototype.norm = function () {
return this.x*this.x + this.y*this.y + this.z*this.z
}
L.get("y", new XYZ(3,1,4))
// 1
L.set("y", -1, new XYZ(3,1,4))
// { x: 3, y: -1, z: 4 } Also not mentioned previously, but object targeting traversals also work on non- L.modify(L.sequence, x => -x, new XYZ(3,1,4))
// { x: -3, y: -1, z: -4 }
L.modify(L.branch({x: L.identity, z: L.identity}), x => -x, new XYZ(3,1,4))
// { x: -3, y: 1, z: -4 } Non-objects cannot be accessed, however: L.get("length", "strings are not objects")
// undefined When written through, the result is consistently an L.set("length", 5, "strings are not objects")
// { length: 5 } |
Here are a few random examples of manipulating non- Index lenses can access strings, typed arrays and pretty much anything that has a L.get(1, "LOLA")
// 'O'
(function () { return L.get(1, arguments) })(true, "args", 2)
// 'args' When written through, the result is always an L.set(1, "A", "LOLA")
// [ 'L', 'A', 'L', 'A' ] To fix the result type, if desired, L.set([L.rewrite(R.join("")), 1], "A", "LOLA")
// 'LALA' The
And L.modify([L.rewrite(xs => Int8Array.from(xs)), L.sequence],
x => x+1,
Int8Array.of(0, 127))
// Int8Array [ 1, -128 ] |
…-semantics Relaxed treatment of arrays & objects to address #40
When using this library with graphqljs, the data received by the server becomes difficult to work with as it is formed using Perhaps using I really don't know but right now I have to make custom lenses for this Thanks |
I feel your pain. This is a known issue, #127, that comes up every now and then. I'll try and see if I could find a few days next week to make version 14.0.0 happen. |
Thanks |
Currently property lenses,
L.prop
, only deal with objects whose constructor is the fundamental object constructorObject
. (Index lenses have a corresponding association with theArray
constructor.) This has been by intention, because non-plain objects may need to be created by calling the constructor function. Naïvely creating an object with a non-Object
constructor and assigning properties to it may not produce a correct result.Here is an example of the current behaviour:
Essentially a property lens requires the constructor (or type) of the target to be
Object
. Otherwise the target is treated asundefined
. I believe this behaviour is reasonable and consistent and should not be changed.However, there are cases where one would like to use lenses with objects whose prototypes are not
Object
. There are a number of more or less plausible use cases with different requirements:Object
constructors.Object
constructors. It is OK to essentially ignore the non-Object
constructor and simply construct plainObject
s.The text was updated successfully, but these errors were encountered: