<div dir="ltr"><div>With a pointer from Vlad and some study of the lens tutorial, I made a proof of concept at [1].</div><div>I am deliberately not using the existing lens library as I envisage this code ending up in GHC.</div><div><br></div><div>Alan</div><div><br></div><div>[1]  <a href="https://github.com/alanz/ghc-exactprint/blob/f218e211c47943c216a2e25d7855f98a0355f6b8/src/Language/Haskell/GHC/ExactPrint/ExactPrint.hs#L689-L723">https://github.com/alanz/ghc-exactprint/blob/f218e211c47943c216a2e25d7855f98a0355f6b8/src/Language/Haskell/GHC/ExactPrint/ExactPrint.hs#L689-L723</a><div><br><br></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, 3 Oct 2021 at 18:52, Vladislav Zavialov <<a href="mailto:vladislav@serokell.io">vladislav@serokell.io</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Alan,<br>
<br>
Your pair of functions can be packaged up as a single function, so that<br>
<br>
        getEpa :: a -> EpaLocation<br>
        setEpa :: a -> EpaLocation -> a<br>
<br>
becomes<br>
<br>
        lensEpa :: forall f. Functor f => (EpaLocation -> f EpaLocation) -> (a -> f a)  <br>
<br>
And the get/set parts can be recovered by instantiating `f` to either Identity or Const.<br>
<br>
The nice thing about lenses is that they compose, so that if you need nested access, you could define several lenses, compose them together, and then reach deep into a data structure. Then lenses might offer some simplification. Otherwise, an ordinary getter/setter pair is just as good.<br>
<br>
- Vlad<br>
<br>
> On 3 Oct 2021, at 20:40, Alan & Kim Zimmerman <<a href="mailto:alan.zimm@gmail.com" target="_blank">alan.zimm@gmail.com</a>> wrote:<br>
> <br>
> Hi all<br>
> <br>
> I am working on a variant of the exact printer which updates the annotation locations from the `EpaSpan` version to the `EpaDelta` version, as the printing happens<br>
> <br>
> data EpaLocation = EpaSpan RealSrcSpan<br>
>                  | EpaDelta DeltaPos<br>
> <br>
> The function doing the work is this<br>
> <br>
> markAnnKw :: (Monad m, Monoid w)<br>
>   => EpAnn a -> (a -> EpaLocation) -> (a -> EpaLocation -> a) -> AnnKeywordId -> EP w m (EpAnn a)<br>
> <br>
> which gets an annotation, a function to pull a specific location out, and one to update it.<br>
> <br>
> I do not know much about lenses, but have a feeling that I could simplify things by using one.<br>
> <br>
> Can anyone give me any pointers?<br>
> <br>
> Alan<br>
> <br>
> _______________________________________________<br>
> ghc-devs mailing list<br>
> <a href="mailto:ghc-devs@haskell.org" target="_blank">ghc-devs@haskell.org</a><br>
> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs</a><br>
<br>
</blockquote></div>