Lens, with ability to create a data-field when it's missing

Dear All, I really am enjoying the lens (it is tough to learn, though :) Recently, I've been trying to implement a dynamic object --- a collection of methods that you can update at run-time --- using lens [1][2][3]. After several attempts, I think I have located the center of my problem: Lens with the ability "to create a data-field when it's missing." My question: is it possible? There are many excellent examples of partial lenses in the lens library, such as '_head' from Data.List.Lens 'dynamic' from Data.Dynamic.Lens . To me, they seem to share the following set of common behavior (allow me to use inaccurate terms...) - set l a s : if the field is present, insert 'a'; otherwise, do nothing. - over l f s : if the field is present, map 'f' over it. otherwise, do nothing. - preview l s : if the field is present, return 'Just a'. otherwise, return 'Nothing' . Instead, I want the following set of behaviors: - set l a s : if the field is present, insert 'a'; otherwise, *create the field* and insert 'a'. - over l f s : if the field is present, map 'f' over it. otherwise, do nothing. - preview l s : if the field is present, return 'Just a'. otherwise, return 'Nothing' . For example, the current behavior of _head is >>> [] & _head .~ 1 [] I want to implement a variant _head' , such that >>> [] & _head' .~ 1 [1] Let us call this behavior 'Member' for the moment. I have a implementation of 'Member' [4][5] but they are unsatisfactory. [4] involves runtime errors and breaking of lens laws. [5] shows that we can "create a field" only if we treat Dynamic explicitly out of lens context. I don't know how 'Member' will fit in the lens hierarchy http://i.imgur.com/FgfVW.png or even if it fits at all. Member is weaker than Getter and probably is a Fold since you have only partial getting (^?) for Member. Member is weaker than Prism since you cannot construct a whole Object from just one Member. On the other hand, setter side of Member requires (s -> b -> t) interface of a Lens, because the setter need to update the whole Object when the field under concern is missing. That said, let me put this question in another way; " We can construct a (Simple Lens s a) from (getter :: s -> a) and (setter :: s -> a -> s), and we can construct a (Getter s a) from (getter :: s -> a). Then why we cannot construct a (Simple Setter s a) from (setter :: s -> a -> s) ? " Does Member deserve a new node in The Lens Hierarchy tree? Or can we implement it by combinations of existing prisms, folds etc? Or does it fall outside of the lens framework? I appreciate any comments. Takayuki [1] https://github.com/nushio3/practice/tree/master/duck [2] http://d.hatena.ne.jp/nushio/20121226#p2 (Japanese) [3] http://hackage.haskell.org/packages/archive/dynamic-object/0.1.0.1/doc/html/... [4] https://github.com/nushio3/practice/blob/master/lens/newfield.hs [5] https://github.com/nushio3/practice/blob/master/lens/object-4.hs -- Takayuki MURANUSHI The Hakubi Center for Advanced Research, Kyoto University http://www.hakubi.kyoto-u.ac.jp/02_mem/h22/muranushi.html

Dear everyone,
With help of many, I found ways to implement most of the features I
have wanted, and I can release the new dynamic-object package.
http://hackage.haskell.org/package/dynamic-object
Thank you in advance for your supports,
Takayuki
2013/1/3 Takayuki Muranushi
Dear All, I really am enjoying the lens (it is tough to learn, though :)
Recently, I've been trying to implement a dynamic object --- a collection of methods that you can update at run-time --- using lens [1][2][3]. After several attempts, I think I have located the center of my problem:
Lens with the ability "to create a data-field when it's missing." My question: is it possible?
There are many excellent examples of partial lenses in the lens library, such as '_head' from Data.List.Lens 'dynamic' from Data.Dynamic.Lens . To me, they seem to share the following set of common behavior (allow me to use inaccurate terms...)
- set l a s : if the field is present, insert 'a'; otherwise, do nothing. - over l f s : if the field is present, map 'f' over it. otherwise, do nothing. - preview l s : if the field is present, return 'Just a'. otherwise, return 'Nothing' .
Instead, I want the following set of behaviors:
- set l a s : if the field is present, insert 'a'; otherwise, *create the field* and insert 'a'. - over l f s : if the field is present, map 'f' over it. otherwise, do nothing. - preview l s : if the field is present, return 'Just a'. otherwise, return 'Nothing' .
For example, the current behavior of _head is >>> [] & _head .~ 1 [] I want to implement a variant _head' , such that >>> [] & _head' .~ 1 [1]
Let us call this behavior 'Member' for the moment.
I have a implementation of 'Member' [4][5] but they are unsatisfactory. [4] involves runtime errors and breaking of lens laws. [5] shows that we can "create a field" only if we treat Dynamic explicitly out of lens context.
I don't know how 'Member' will fit in the lens hierarchy http://i.imgur.com/FgfVW.png or even if it fits at all. Member is weaker than Getter and probably is a Fold since you have only partial getting (^?) for Member. Member is weaker than Prism since you cannot construct a whole Object from just one Member. On the other hand, setter side of Member requires (s -> b -> t) interface of a Lens, because the setter need to update the whole Object when the field under concern is missing.
That said, let me put this question in another way;
" We can construct a (Simple Lens s a) from (getter :: s -> a) and (setter :: s -> a -> s), and we can construct a (Getter s a) from (getter :: s -> a). Then why we cannot construct a (Simple Setter s a) from (setter :: s -> a -> s) ? "
Does Member deserve a new node in The Lens Hierarchy tree? Or can we implement it by combinations of existing prisms, folds etc? Or does it fall outside of the lens framework?
I appreciate any comments. Takayuki
[1] https://github.com/nushio3/practice/tree/master/duck [2] http://d.hatena.ne.jp/nushio/20121226#p2 (Japanese) [3] http://hackage.haskell.org/packages/archive/dynamic-object/0.1.0.1/doc/html/... [4] https://github.com/nushio3/practice/blob/master/lens/newfield.hs [5] https://github.com/nushio3/practice/blob/master/lens/object-4.hs
-- Takayuki MURANUSHI The Hakubi Center for Advanced Research, Kyoto University http://www.hakubi.kyoto-u.ac.jp/02_mem/h22/muranushi.html
-- Takayuki MURANUSHI The Hakubi Center for Advanced Research, Kyoto University http://www.hakubi.kyoto-u.ac.jp/02_mem/h22/muranushi.html
participants (1)
-
Takayuki Muranushi