<div dir="ltr"><div><div><div><div>Hello there,<br><br></div>I&#39;m starting to use a bit more extensively the lens package. It is clearly very powerful, but it feels like a maze of related components (Setting/Setter/Lens&#39;/LensLike/Lens/Traversal/Traversal&#39;) which can be swapped for one another except when they can&#39;t.<br>
<br></div>The first (concrete) problem I ran into is how to update the members of a set with the result of an IO action. I have managed to do this with a pure function (prefixName) but I&#39;m not sure of how to do this with promptName.<br>
<br></div>Full program below:<br><br>&nbsp; {-# LANGUAGE TemplateHaskell #-}<br>&nbsp; import Control.Lens<br>&nbsp; import Data.Set<br>&nbsp; import Data.Set.Lens<br><br>&nbsp; data Dog = Dog { _name :: String, _legs :: Int } <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deriving (&hellip;)<br>
&nbsp; makeLenses &#39;&#39;Dog<br><br>&nbsp; data Dogs = Dogs { _dogs :: Set Dog } <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; deriving Show<br>&nbsp; makeLenses &#39;&#39;Dogs<br><br>&nbsp; fourLegs :: Traversal&#39; Dog Dog<br>&nbsp; fourLegs = filtered (ëd -&gt; d^.legs == 4)<br>
<br>&nbsp; promptName :: String -&gt; IO String<br>&nbsp; promptName dogName = do<br>&nbsp; &nbsp; &nbsp; putStr $ &quot;New name for &quot; ++ dogName<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getLine<br><br>&nbsp; prefixName :: Dog -&gt; Dog<br>&nbsp; prefixName dog = set name (&quot;PREFIXED: &quot; ++ dog^.name) dog<br>
<br>&nbsp; main :: IO ()<br>&nbsp; main = do<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; let fido = Dog &quot;fido&quot; 4 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; let milou = Dog &quot;milou&quot; 4 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; let cripple = Dog &quot;cripple&quot; 3 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; let doggies = Dogs $ fromList [fido, milou, cripple]<br>
<br></div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- prefix dog names via a pure function<br><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; let doggies&#39; = over (dogs.setmapped) prefixName doggies<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print doggies&#39;<br></div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- change dog names by prompting the user ?<br>
</div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ()<br><br></div><div>Help would be appreciated (in particular, &#39;cripple&#39; would love to be renamed).<br></div><div><br></div><div>Since I was struggling with the library, I had the idea to look at the internals, but got stuck at the definition of Lens:<br>
<pre><span class="">type</span> <span class="">Lens</span> <span class="">s</span> <span class="">t</span> <span class="">a</span> <span class="">b</span> <span class="">=</span> <span class="">forall</span> <span class="">f</span><span class="">.</span> <span class="">Functor</span> <span class="">f</span> <span class="">=&gt;</span> <span class="">(</span><span class="">a</span> <span class="">-&gt;</span> <span class="">f</span> <span class="">b</span><span class="">)</span> <span class="">-&gt;</span> <span class="">s</span> <span class="">-&gt;</span> <span class="">f</span> <span class="">t<br>
</span></pre>a) I&#39;m not sure why the explicit forall is needed here (isn&#39;t this equivalent to just Functor f =&gt; ...)?<br></div><div>b) My understanding is that a lens packs both getter and setters, but I don&#39;t know which is supposed to be which here...<br>
</div><div>c) Is there any kind of in-depth guide to Control.Lens somewhere? I have found some examples and tutorials but nothing that seemed to do more than scratch the surface.<br><br></div><div>Thanks,<br><br>Emm<br></div>
</div>