<div dir="ltr"><div class="gmail_default" style="font-size:small">You can use the "non" lens for this:</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small"><div class="gmail_default">λ> view (at "a" . non "") (Data.Map.fromList [("a", "x"), ("b", "y")])</div><div class="gmail_default">"x"</div><div class="gmail_default">λ> view (at "c" . non "") (Data.Map.fromList [("a", "x"), ("b", "y")])</div><div class="gmail_default">""</div><div class="gmail_default">λ> set (at "c" . non "") "z" (Data.Map.fromList [("a", "x"), ("b", "y")])</div><div class="gmail_default">fromList [("a","x"),("b","y"),("c","z")]<br></div><div class="gmail_default"><br></div><div class="gmail_default">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.</div><div class="gmail_default"><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 20, 2016 at 12:02 PM, Jan von Löwenstein <span dir="ltr"><<a href="mailto:jan.loewenstein@gmail.com" target="_blank">jan.loewenstein@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Thanks for looking into this. Apparently I did not yet express my question properly.<div><br></div><div>In short:</div><div>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.</div><div><br></div><div>More concrete, given the following Json fragment (out of a configuration file):</div><div><div>"disks": {</div><div> "system": "/dev/xvda",</div><div> "ephemeral": "/dev/sdb",</div><div> "persistent": {</div><div> "<disk identifier>" : { "path" : "/container/mounted/volume" }</div><div> }</div><div> },</div></div><div><br></div><div>I want to add a persistent disk `my-disk` with a given path `/yet/another/volume` and I don't want to handle</div><div><ul><li><font size="2">there is no node 'my-disk' </font></li><li><font size="2">there is<span class="m_3285260217445851836inbox-inbox-Apple-converted-space"> </span>no node 'persistent'</font></li><li><font size="2">there is no node 'disks'</font></li></ul><div><font size="2">Given a function </font></div></div><div><font size="2"><div> defaultsToEmpty :: Maybe (Value) -> Maybe (Value)</div><div> defaultsToEmpty Nothing = Just $ Object HashMap.empty</div><div> defaultsToEmpty m = m</div><div>I can do</div><div> json & key "disks" %~ defaultsToEmpty</div><div> &<span class="m_3285260217445851836inbox-inbox-Apple-converted-space"> </span>key "disks".key "persistent" %~ defaultsToEmpty</div></font> &<span class="m_3285260217445851836inbox-inbox-inbox-inbox-Apple-converted-space" style="font-size:small"> </span><span style="font-size:small">key "disks".key "persistent".key diskId %~ defaultsToEmpty</span></div><div><font size="2">but this doesn't look nice and was wondering if lenses can do better.</font></div><div><br></div><div><br></div></div><div class="HOEnZb"><div class="h5"><br><div class="gmail_quote"><div dir="ltr">David McBride <<a href="mailto:toad3k@gmail.com" target="_blank">toad3k@gmail.com</a>> schrieb am Di., 20. Dez. 2016 um 16:59 Uhr:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_3285260217445851836gmail_msg">Sorry, replying to list:</div><div dir="ltr" class="m_3285260217445851836gmail_msg"><br class="m_3285260217445851836gmail_msg"><br class="m_3285260217445851836gmail_msg">Would that not just be<br class="m_3285260217445851836gmail_msg"><br class="m_3285260217445851836gmail_msg">json & key "outer" .~ object ["inner", "new-value"]</div><div class="gmail_extra m_3285260217445851836gmail_msg"><br class="m_3285260217445851836gmail_msg"><div class="gmail_quote m_3285260217445851836gmail_msg">On Tue, Dec 20, 2016 at 8:26 AM, Jan von Löwenstein <span dir="ltr" class="m_3285260217445851836gmail_msg"><<a href="mailto:jan.loewenstein@gmail.com" class="m_3285260217445851836gmail_msg" target="_blank">jan.loewenstein@gmail.com</a>></span> wrote:<br class="m_3285260217445851836gmail_msg"><blockquote class="gmail_quote m_3285260217445851836gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_3285260217445851836gmail_msg">I guess I haven't explained well what I am looking for.<div class="m_3285260217445851836gmail_msg"><br class="m_3285260217445851836gmail_msg"></div><div class="m_3285260217445851836gmail_msg">I want to set values deep inside a json structure, no matter if the full structure already exists.</div><div class="m_3285260217445851836gmail_msg"><br class="m_3285260217445851836gmail_msg"></div><div class="m_3285260217445851836gmail_msg">Go into "outer", if it doesn't exist make it an empty object. </div><div class="m_3285260217445851836gmail_msg">From there go into "inner" and set it to "new-value".</div><div class="m_3285260217445851836gmail_msg"><br class="m_3285260217445851836gmail_msg"></div><div class="m_3285260217445851836gmail_msg">The first part should be arbitrarily deep.</div><div class="m_3285260217445851836gmail_msg"><br class="m_3285260217445851836gmail_msg"></div><div class="m_3285260217445851836gmail_msg">Best</div><span class="m_3285260217445851836m_-8181045627324967617HOEnZb m_3285260217445851836gmail_msg"><font color="#888888" class="m_3285260217445851836gmail_msg"><div class="m_3285260217445851836gmail_msg">Jan</div></font></span></div><div class="m_3285260217445851836m_-8181045627324967617HOEnZb m_3285260217445851836gmail_msg"><div class="m_3285260217445851836m_-8181045627324967617h5 m_3285260217445851836gmail_msg"><br class="m_3285260217445851836gmail_msg"><div class="gmail_quote m_3285260217445851836gmail_msg"><div dir="ltr" class="m_3285260217445851836gmail_msg">Benjamin Edwards <<a href="mailto:edwards.benj@gmail.com" class="m_3285260217445851836gmail_msg" target="_blank">edwards.benj@gmail.com</a>> schrieb am Di., 20. Dez. 2016 um 13:42 Uhr:<br class="m_3285260217445851836gmail_msg"></div><blockquote class="gmail_quote m_3285260217445851836gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">If the desired function doesn't inspect the input then why not just use const <<thing you want>> ?<br class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"><br class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"></div>As to the lenses part: If you use a prism and it doesn't match, then it's a noop.<br class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"></div><br class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"><div class="gmail_quote m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"></div><div class="gmail_quote m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"><div dir="ltr" class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">On Tue, 20 Dec 2016 at 09:38 Jan von Löwenstein <<a href="mailto:jan.loewenstein@gmail.com" class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg" target="_blank">jan.loewenstein@gmail.com</a>> wrote:<br class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"></div></div><div class="gmail_quote m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"><blockquote class="gmail_quote m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">Hi,<div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"><br class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"></div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">I want to have code that produces the following result no matter if input A or B was given:</div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"><br class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"></div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">Result:</div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">{</div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"> "outer" : {</div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"> "inner" : "new-value"</div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"> }</div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">}</div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"><br class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"></div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">A: </div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">{</div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"> "outer" : {</div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"> "inner" : "old-value"</div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"> }</div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">}</div></div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"><br class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"></div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">B:</div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">{}</div></div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"><br class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"></div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">`json & key "outer"._Object.key "inner" .~ "new-value"` didn't work.</div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"><br class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"></div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">Is what I want even possible with lenses?</div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"><br class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"></div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">Best</div><div class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">Jan</div></div></blockquote></div><div class="gmail_quote m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg"><blockquote class="gmail_quote m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
______________________________<wbr>_________________<br class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">
Haskell-Cafe mailing list<br class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">
To (un)subscribe, modify options or view archives go to:<br class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/haskell-<wbr>cafe</a><br class="m_3285260217445851836m_-8181045627324967617m_-5353922401637114217gmail_msg m_3285260217445851836gmail_msg">
Only members subscribed via the mailman list are allowed to post.</blockquote></div>
</blockquote></div>
</div></div><br class="m_3285260217445851836gmail_msg">______________________________<wbr>_________________<br class="m_3285260217445851836gmail_msg">
Haskell-Cafe mailing list<br class="m_3285260217445851836gmail_msg">
To (un)subscribe, modify options or view archives go to:<br class="m_3285260217445851836gmail_msg">
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" class="m_3285260217445851836gmail_msg" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/haskell-<wbr>cafe</a><br class="m_3285260217445851836gmail_msg">
Only members subscribed via the mailman list are allowed to post.<br class="m_3285260217445851836gmail_msg"></blockquote></div><br class="m_3285260217445851836gmail_msg"></div>
______________________________<wbr>_________________<br class="m_3285260217445851836gmail_msg">
Haskell-Cafe mailing list<br class="m_3285260217445851836gmail_msg">
To (un)subscribe, modify options or view archives go to:<br class="m_3285260217445851836gmail_msg">
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" class="m_3285260217445851836gmail_msg" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/haskell-<wbr>cafe</a><br class="m_3285260217445851836gmail_msg">
Only members subscribed via the mailman list are allowed to post.</blockquote></div>
</div></div><br>______________________________<wbr>_________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/haskell-<wbr>cafe</a><br>
Only members subscribed via the mailman list are allowed to post.<br></blockquote></div><br></div>