[Haskell-cafe] Lenses: Changing/creating values deep inside JSON or HashMap

David Fox dsf at seereason.com
Fri Dec 23 17:02:36 UTC 2016


Its funny how with lens, you first try something and it doesn't work.  Then
you work on it a lot, and when you finally get it working it looks exactly
like the first thing you tried.  Mysterious.

On Thu, Dec 22, 2016 at 12:00 AM, Jan von Löwenstein <
jan.loewenstein at gmail.com> wrote:

> Thanks a lot.
>
> I finally figured out how to use `non` properly.
>
> I tried hard to get it working with `key` from Data.Aeson.Lens.
> Without a Maybe in the signature of `key` I didn't get `non` to work. Took
> some time to realize this.
>
> Now I switched to using `at` and everything is fine (i.e. compiles).
>
> David Fox <dsf at seereason.com> schrieb am Di., 20. Dez. 2016 um 22:59 Uhr:
>
>> You can use the "non" lens for this:
>>
>> λ> view (at "a" . non "") (Data.Map.fromList [("a", "x"), ("b", "y")])
>> "x"
>> λ> view (at "c" . non "") (Data.Map.fromList [("a", "x"), ("b", "y")])
>> ""
>> λ> set (at "c" . non "") "z" (Data.Map.fromList [("a", "x"), ("b", "y")])
>> fromList [("a","x"),("b","y"),("c","z")]
>>
>> So it will return the non argument when an entry doesn't exist, and it
>> will create values using the non argument when you try to set an entry that
>> doesn't exist.
>>
>>
>> On Tue, Dec 20, 2016 at 12:02 PM, Jan von Löwenstein <
>> jan.loewenstein at gmail.com> wrote:
>>
>> Thanks for looking into this. Apparently I did not yet express my
>> question properly.
>>
>> In short:
>> Given a deeply nested data structure (e.g. Json with nested objects) I
>> want to set a leaf value without considering which parent and or sibling
>> nodes already exist.
>>
>> More concrete, given the following Json fragment (out of a configuration
>> file):
>> "disks": {
>>        "system": "/dev/xvda",
>>        "ephemeral": "/dev/sdb",
>>        "persistent": {
>>            "<disk identifier>" : { "path" : "/container/mounted/volume" }
>>        }
>>      },
>>
>> I want to add a persistent disk `my-disk` with a given path
>> `/yet/another/volume` and I don't want to handle
>>
>>    - there is no node 'my-disk'
>>    - there is no node 'persistent'
>>    - there is no node 'disks'
>>
>> Given a function
>>   defaultsToEmpty :: Maybe (Value) -> Maybe (Value)
>>   defaultsToEmpty Nothing = Just $ Object HashMap.empty
>>   defaultsToEmpty m = m
>> I can do
>>   json & key "disks" %~ defaultsToEmpty
>>           & key "disks".key "persistent" %~ defaultsToEmpty
>>           & key "disks".key "persistent".key diskId %~ defaultsToEmpty
>> but this doesn't look nice and was wondering if lenses can do better.
>>
>>
>>
>> David McBride <toad3k at gmail.com> schrieb am Di., 20. Dez. 2016 um
>> 16:59 Uhr:
>>
>> Sorry, replying to list:
>>
>>
>> Would that not just be
>>
>> json & key "outer" .~ object ["inner", "new-value"]
>>
>> On Tue, Dec 20, 2016 at 8:26 AM, Jan von Löwenstein <
>> jan.loewenstein at gmail.com> wrote:
>>
>> I guess I haven't explained well what I am looking for.
>>
>> I want to set values deep inside a json structure, no matter if the full
>> structure already exists.
>>
>> Go into "outer", if it doesn't exist make it an empty object.
>> From there go into "inner" and set it to "new-value".
>>
>> The first part should be arbitrarily deep.
>>
>> Best
>> Jan
>>
>> Benjamin Edwards <edwards.benj at gmail.com> schrieb am Di., 20. Dez. 2016
>> um 13:42 Uhr:
>>
>> If the desired function doesn't inspect the input then why not just use
>> const <<thing you want>> ?
>>
>> As to the lenses part: If you use a prism and it doesn't match, then it's
>> a noop.
>>
>> On Tue, 20 Dec 2016 at 09:38 Jan von Löwenstein <
>> jan.loewenstein at gmail.com> wrote:
>>
>> Hi,
>>
>> I want to have code that produces the following result no matter if input
>> A or B was given:
>>
>> Result:
>> {
>>   "outer" : {
>>                   "inner" : "new-value"
>>                 }
>> }
>>
>> A:
>> {
>>   "outer" : {
>>                   "inner" : "old-value"
>>                 }
>> }
>>
>> B:
>> {}
>>
>> `json & key "outer"._Object.key "inner" .~ "new-value"` didn't work.
>>
>> Is what I want even possible with lenses?
>>
>> Best
>> Jan
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> To (un)subscribe, modify options or view archives go to:
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>> Only members subscribed via the mailman list are allowed to post.
>>
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> To (un)subscribe, modify options or view archives go to:
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>> Only members subscribed via the mailman list are allowed to post.
>>
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> To (un)subscribe, modify options or view archives go to:
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>> Only members subscribed via the mailman list are allowed to post.
>>
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> To (un)subscribe, modify options or view archives go to:
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>> Only members subscribed via the mailman list are allowed to post.
>>
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20161223/d8058c93/attachment.html>


More information about the Haskell-Cafe mailing list