<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Lenses – Haskell – Aelve Guide</title><id>https://guide.aelve.com/haskell/feed/category/sth6l9jl</id><updated>2016-03-10T11:06:40Z</updated><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/feed/category/sth6l9jl"/><entry><id>ov2yi6mf</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">lens</title><updated>2016-03-10T11:06:40Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;lens&lt;/span&gt;

  
  (&lt;a href=&#34;https://hackage.haskell.org/package/lens&#34;&gt;Hackage&lt;/a&gt;)
&lt;/h1&gt;&lt;p&gt;The most widely used and most featureful lens library. Can be overkill in some cases, but is often the best fit for applications. Can also be hard to understand, and hence use (since without understanding what happens inside, you&#39;re bound to stumble somewhere sooner or later).&lt;/p&gt;
&lt;h2&gt;Pros&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;The most popular lens library, by a huge margin (and one of most popular &lt;a href=&#34;https://hackage.haskell.org/packages/top&#34;&gt;overall&lt;/a&gt; on Hackage).&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Contains pretty much everything you could want – in addition to usual lenses (for manipulating lists, maps, tuples, and standard types like &lt;code&gt;Maybe&lt;/code&gt;/&lt;code&gt;Either&lt;/code&gt;/etc), lens has functions for manipulating filepaths, Template Haskell structures, generics, complex numbers, exceptions, &lt;code&gt;Text&lt;/code&gt;, &lt;code&gt;Vector&lt;/code&gt;, &lt;code&gt;ByteString&lt;/code&gt;, and so on. Other libraries aren&#39;t even close.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Unlike most other libraries, has prisms – a kind of lenses that can act both as constructors and deconstructors at once. They can be pretty useful when you&#39;re dealing with exceptions, Template Haskell, JSON, sum types, etc.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Probably the most performant one.&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Cons&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;Takes a lot of time to compile, and has a lot of dependencies as well.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Some of its advanced features are very intimidating, and the whole library may seem overengineered. See &lt;a href=&#34;http://fvisser.nl/post/2013/okt/11/why-i-dont-like-the-lens-library.html&#34;&gt;this post&lt;/a&gt;.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Once you start using lenses for &lt;em&gt;everything&lt;/em&gt; (which happens often to users of lens), your code may start not looking like Haskell much and people not used to this style will have a hard time understanding it. See &lt;a href=&#34;https://ro-che.info/articles/2014-04-24-lens-unidiomatic&#34;&gt;this post&lt;/a&gt;.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Doesn&#39;t have (unlawful) monadic lenses (i.e. you can&#39;t write something like &lt;code&gt;Lens&#39; (IORef a) a&lt;/code&gt;).&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Ecosystem&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Lenses for types provided in various libraries:
&lt;a href=&#34;https://hackage.haskell.org/package/lens-aeson&#34;&gt;lens-aeson&lt;/a&gt;,
&lt;a href=&#34;https://hackage.haskell.org/package/lens-datetime&#34;&gt;lens-datetime&lt;/a&gt;,
&lt;a href=&#34;https://hackage.haskell.org/package/xml-lens&#34;&gt;xml-lens&lt;/a&gt;,
&lt;a href=&#34;https://hackage.haskell.org/package/pandoc-lens&#34;&gt;pandoc-lens&lt;/a&gt;,
&lt;a href=&#34;https://hackage.haskell.org/package/cabal-lenses&#34;&gt;cabal-lenses&lt;/a&gt;,
&lt;a href=&#34;https://hackage.haskell.org/package/wai-lens&#34;&gt;wai-lens&lt;/a&gt;,
&lt;a href=&#34;https://hackage.haskell.org/package/twitter-types-lens&#34;&gt;twitter-types-lens&lt;/a&gt;,
&lt;a href=&#34;hk&#34;&gt;simpleirc-lens&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Testing your lenses:
&lt;a href=&#34;https://hackage.haskell.org/package/smallcheck-lens&#34;&gt;smallcheck-lens&lt;/a&gt; (for &lt;a href=&#34;https://hackage.haskell.org/package/smallcheck&#34;&gt;smallcheck&lt;/a&gt;),
&lt;a href=&#34;https://hackage.haskell.org/package/lens-properties&#34;&gt;lens-properties&lt;/a&gt; (for &lt;a href=&#34;https://hackage.haskell.org/package/quickcheck&#34;&gt;quickcheck&lt;/a&gt;),
&lt;a href=&#34;https://hackage.haskell.org/package/tasty-lens&#34;&gt;tasty-lens&lt;/a&gt; (for &lt;a href=&#34;https://hackage.haskell.org/package/tasty&#34;&gt;tasty&lt;/a&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lenses as interfaces for other libraries:
&lt;a href=&#34;https://hackage.haskell.org/package/zlib-lens&#34;&gt;zlib-lens&lt;/a&gt; (compress things using lenses),
&lt;a href=&#34;https://hackage.haskell.org/package/lens-regex&#34;&gt;lens-regex&lt;/a&gt; (use regexes with lenses)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Various:
&lt;a href=&#34;https://hackage.haskell.org/package/lens-tutorial&#34;&gt;lens-tutorial&lt;/a&gt; (a tutorial package),
&lt;a href=&#34;https://hackage.haskell.org/package/lens-action&#34;&gt;lens-action&lt;/a&gt; (monadic getters),
&lt;a href=&#34;https://hackage.haskell.org/package/total&#34;&gt;total&lt;/a&gt; (a library for total pattern matching with lenses – see &lt;a href=&#34;http://www.haskellforall.com/2015/01/total-100-exhaustive-pattern-matching.html&#34;&gt;this post&lt;/a&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Notes&lt;/h2&gt;&lt;h1&gt;&lt;span id=&#34;item-notes-ov2yi6mf-links&#34;&gt;&lt;/span&gt;Links&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://hackage.haskell.org/package/lens-tutorial-1.0.1/docs/Control-Lens-Tutorial.html&#34;&gt;tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://en.wikibooks.org/wiki/Haskell/Lenses_and_functional_references&#34;&gt;longer tutorial with exercises&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://duplode.github.io/posts/lenses-you-can-make-at-home.html&#34;&gt;a short post about the idea behind van Laarhoven lenses&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://artyom.me/#lens-over-tea&#34;&gt;in-depth posts about how lens works and how it&#39;s implemented&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ekmett/lens/wiki/Operators&#34;&gt;a cheatsheet for lens operators&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If your question isn&#39;t answered here, there&#39;s an IRC channel (#haskell-lens) which you can join &lt;a href=&#34;https://webchat.freenode.net/&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-ov2yi6mf-imports&#34;&gt;&lt;/span&gt;Imports&lt;/h1&gt;&lt;p&gt;&lt;code&gt;Control.Lens&lt;/code&gt; reexports most things you might need. However, to get additional lenses, import:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Control.Exception.Lens&lt;/code&gt; for lenses for things from &lt;code&gt;Control.Exception&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Data.Bits.Lens&lt;/code&gt; for manipulation of bits&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Data.Complex.Lens&lt;/code&gt; for things from &lt;code&gt;Data.Complex&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Language.Haskell.TH.Lens&lt;/code&gt; for things from &lt;code&gt;Language.Haskell.TH&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;...you get the idea&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-ov2yi6mf-basic-operations&#34;&gt;&lt;/span&gt;Basic operations&lt;/h1&gt;&lt;p&gt;Extract a value from a bigger value: &lt;code&gt;value ^. lens&lt;/code&gt; or &lt;code&gt;view lens value&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; (&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;) &lt;span class=&#34;fu&#34;&gt;^.&lt;/span&gt; _1
&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Set a part of a bigger value: &lt;code&gt;value &amp;amp; lens .~ x&lt;/code&gt; or &lt;code&gt;set lens x value&lt;/code&gt; (&lt;code&gt;.~&lt;/code&gt; is a synonym for &lt;code&gt;set&lt;/code&gt; and &lt;code&gt;&amp;amp;&lt;/code&gt; just applies a function to a value):&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; (&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;) &lt;span class=&#34;fu&#34;&gt;&amp;amp;&lt;/span&gt; _1 &lt;span class=&#34;fu&#34;&gt;.~&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;10&lt;/span&gt;
(&lt;span class=&#34;dv&#34;&gt;10&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Modify a part of a bigger value: &lt;code&gt;value &amp;amp; lens %~ f&lt;/code&gt; or &lt;code&gt;over lens f value&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; (&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;) &lt;span class=&#34;fu&#34;&gt;&amp;amp;&lt;/span&gt; _1 &lt;span class=&#34;fu&#34;&gt;%~&lt;/span&gt; negate
(&lt;span class=&#34;fu&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(Lens is known for its operators (120 and counting); you can find a table of them &lt;a href=&#34;https://github.com/ekmett/lens/wiki/Operators&#34;&gt;here&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;Generate lenses for your record type:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;ot&#34;&gt;{-# LANGUAGE TemplateHaskell #-}&lt;/span&gt;

&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;FullName&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;FullName&lt;/span&gt; {
&lt;span class=&#34;ot&#34;&gt;  _name       ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;,
&lt;span class=&#34;ot&#34;&gt;  _middleName ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Maybe&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;,
&lt;span class=&#34;ot&#34;&gt;  _surname    ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Maybe&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt; }

&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Person&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Person&lt;/span&gt; {
&lt;span class=&#34;ot&#34;&gt;  _fullName ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;FullName&lt;/span&gt;,
&lt;span class=&#34;ot&#34;&gt;  _age      ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; }

makeLenses &lt;span class=&#34;ch&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;FullName&lt;/span&gt;
makeLenses &lt;span class=&#34;ch&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Person&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And use them:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; theName &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;FullName&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Richard&amp;quot;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Nothing&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Just&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Ellys&amp;quot;&lt;/span&gt;)
&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; richard &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Person&lt;/span&gt; theName &lt;span class=&#34;dv&#34;&gt;28&lt;/span&gt;

&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; richard &lt;span class=&#34;fu&#34;&gt;^.&lt;/span&gt; fullName &lt;span class=&#34;fu&#34;&gt;.&lt;/span&gt; surname
&lt;span class=&#34;dt&#34;&gt;Just&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Ellys&amp;quot;&lt;/span&gt;

&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; richard &lt;span class=&#34;fu&#34;&gt;&amp;amp;&lt;/span&gt; age &lt;span class=&#34;fu&#34;&gt;%~&lt;/span&gt; succ
&lt;span class=&#34;dt&#34;&gt;Person&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;FullName&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Richard&amp;quot;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Nothing&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Just&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;Ellys&amp;quot;&lt;/span&gt;)) &lt;span class=&#34;dv&#34;&gt;29&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-ov2yi6mf-different-types-of-lenses&#34;&gt;&lt;/span&gt;Different types of lenses&lt;/h1&gt;&lt;p&gt;Lens provides several types of accessors – they all do different things and they all can be composed with each other:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Lens&#39; s a&lt;/code&gt; – points at a single part of a structure. The structure has the type &lt;code&gt;s&lt;/code&gt;, the part has the type &lt;code&gt;a&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Lens s t a b&lt;/code&gt; – points at a single part of a structure, but lets you change the type of the part – i.e. if you apply a function of type &lt;code&gt;a -&amp;gt; b&lt;/code&gt;, the whole thing will go from &lt;code&gt;s&lt;/code&gt; to &lt;code&gt;t&lt;/code&gt;. &lt;code&gt;Lens&#39; s a&lt;/code&gt; is the same as &lt;code&gt;Lens s s a a&lt;/code&gt;. An example: &lt;code&gt;_1&lt;/code&gt; has the type &lt;code&gt;Lens (a, x) (b, x) a b&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Traversal&#39; s a&lt;/code&gt; – modifies (or extracts) several parts of a structure (&lt;code&gt;Traversal s t a b&lt;/code&gt; exists as well). If you use &lt;code&gt;set&lt;/code&gt;/&lt;code&gt;over&lt;/code&gt;, it will overwrite/apply a function to all parts. If you use &lt;code&gt;view&lt;/code&gt;/&lt;code&gt;^.&lt;/code&gt;, it will concatenate the extracted values using &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;. To get a list of extracted values, use &lt;code&gt;^..&lt;/code&gt; instead of &lt;code&gt;^.&lt;/code&gt;. An example: &lt;code&gt;both&lt;/code&gt; has the type &lt;code&gt;Traversal&#39; (a, a) a&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; (&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;, &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;) &lt;span class=&#34;fu&#34;&gt;^..&lt;/span&gt; both
[&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;, &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Prism&#39; s a&lt;/code&gt; – converts &lt;code&gt;s&lt;/code&gt; into &lt;code&gt;a&lt;/code&gt; if possible (so it behaves as a &lt;code&gt;Traversal&lt;/code&gt; that either points to a single element or doesn&#39;t point to anything). Anything you can do with a traversal you can do with a prism. A bonus feature is that it can also convert &lt;code&gt;a&lt;/code&gt; into &lt;code&gt;s&lt;/code&gt;. An example: &lt;code&gt;_Right :: Prism (Either x a) (Either x b) a b&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Left&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;^..&lt;/span&gt; _Right
[]

&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Right&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;^..&lt;/span&gt; _Right
[&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;]

&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; _Right &lt;span class=&#34;fu&#34;&gt;#&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;dt&#34;&gt;Right&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By composing prisms you can build bigger prisms and they still would work both as accessors and as constructors.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Iso&#39; s a&lt;/code&gt; – can always convert &lt;code&gt;s&lt;/code&gt; into &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;a&lt;/code&gt; into &lt;code&gt;s&lt;/code&gt;. So, something like a &lt;code&gt;Lens&#39; s a&lt;/code&gt; that you can turn into &lt;code&gt;Lens&#39; a s&lt;/code&gt; using &lt;code&gt;from&lt;/code&gt;. For instance, if you&#39;ve got a lazy &lt;code&gt;Text&lt;/code&gt; and you have a function that works on strict &lt;code&gt;Text&lt;/code&gt;, you can apply it to your lazy &lt;code&gt;Text&lt;/code&gt; like this:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; someLazyText &lt;span class=&#34;fu&#34;&gt;&amp;amp;&lt;/span&gt; strict &lt;span class=&#34;fu&#34;&gt;%~&lt;/span&gt; f&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or you can do the opposite if &lt;code&gt;f&lt;/code&gt; works on lazy &lt;code&gt;Text&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; someStrictText &lt;span class=&#34;fu&#34;&gt;&amp;amp;&lt;/span&gt; from strict &lt;span class=&#34;fu&#34;&gt;%~&lt;/span&gt; f&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are also some other, less powerful variants: &lt;code&gt;Getter&lt;/code&gt; is like &lt;code&gt;Lens&lt;/code&gt; that can&#39;t modify the value, &lt;code&gt;Setter&lt;/code&gt; is like &lt;code&gt;Traversal&lt;/code&gt; that can&#39;t extract parts of the value, &lt;code&gt;Fold&lt;/code&gt; is like &lt;code&gt;Getter&lt;/code&gt; but can extract many elements.&lt;/p&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-ov2yi6mf-lenses-as-functions&#34;&gt;&lt;/span&gt;Lenses as functions&lt;/h1&gt;&lt;p&gt;Lenses are just functions under the hood, and so they can be composed with &lt;code&gt;.&lt;/code&gt;. For instance, &lt;code&gt;_1._2&lt;/code&gt; is a lens that accesses the 2nd element of the 1st element of a tuple. When you compose a lens and a traversal, you get a traversal; a lens and a getter – a getter; a traversal and a setter – a setter; a getter and a setter can&#39;t be composed; etc.&lt;/p&gt;
&lt;p&gt;Here is how &lt;code&gt;Lens&lt;/code&gt; is defined:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Lens&lt;/span&gt; s t a b &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Functor&lt;/span&gt; f &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; (a &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; f b) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; (s &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; f t)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&#39;s quite similar to &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;traverse&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;map&lt;span class=&#34;ot&#34;&gt; ::&lt;/span&gt; (a &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; b) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; ([a] &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; [b])
traverse&lt;span class=&#34;ot&#34;&gt; ::&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Applicative&lt;/span&gt; f, &lt;span class=&#34;dt&#34;&gt;Traversable&lt;/span&gt; t) &lt;span class=&#34;ot&#34;&gt;=&amp;gt;&lt;/span&gt; (a &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; f b) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; t a &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; f (t b)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you compose &lt;code&gt;map.map&lt;/code&gt;, you will get something of type &lt;code&gt;(a -&amp;gt; b) -&amp;gt; ([[a]] -&amp;gt; [[b]])&lt;/code&gt;. It&#39;s almost the same with lenses, except that with lenses there&#39;s also &lt;code&gt;f&lt;/code&gt; in the mix. &lt;code&gt;f&lt;/code&gt; is what lets lenses be used as getters (unlike &lt;code&gt;map&lt;/code&gt;) with a &lt;a href=&#34;https://duplode.github.io/posts/lenses-you-can-make-at-home.html&#34;&gt;clever trick involving &lt;code&gt;Const&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Since lenses are functions, you can apply them directly. For instance, &lt;code&gt;_1 print (1, 2)&lt;/code&gt; is an IO action that would print “1” when executed. Generally, you can use lenses and traversals the same way you can use &lt;code&gt;traverse&lt;/code&gt; or &lt;code&gt;mapM&lt;/code&gt; (and moreover, &lt;code&gt;traverse&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; a &lt;code&gt;Traversal&lt;/code&gt;). This all also means that you can define lenses and traversals in your code without depending on lens-the-package.&lt;/p&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-ov2yi6mf-standard-lenses-and-traversals-and-prisms&#34;&gt;&lt;/span&gt;Standard lenses (and traversals and prisms)&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;_1&lt;/code&gt;, &lt;code&gt;_2&lt;/code&gt;, &lt;code&gt;_3&lt;/code&gt;, ... – the 1st/2nd/3rd/etc element of a tuple (any tuple, since they&#39;re overloaded – e.g. you can use &lt;code&gt;_1&lt;/code&gt; both with &lt;code&gt;(a,b)&lt;/code&gt; and &lt;code&gt;(a,b,c)&lt;/code&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;each&lt;/code&gt; – a traversal for mostly anything (elements of a list, vector, tuple, &lt;code&gt;Map&lt;/code&gt;, characters in a &lt;code&gt;Text&lt;/code&gt;, bytes in a &lt;code&gt;ByteString&lt;/code&gt;, etc).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;at&lt;/code&gt; − a lens for &lt;code&gt;Map&lt;/code&gt;-like things; &lt;code&gt;at &amp;quot;foo&amp;quot;&lt;/code&gt; points at the element with the key &lt;code&gt;&amp;quot;foo&amp;quot;&lt;/code&gt;. An interesting feature of it is that you can use it to insert and delete elements by setting &lt;code&gt;Nothing&lt;/code&gt; or &lt;code&gt;Just v&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; Map.fromList [(&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;world&amp;quot;&lt;/span&gt;)] &lt;span class=&#34;fu&#34;&gt;^.&lt;/span&gt; at &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;dt&#34;&gt;Just&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;world&amp;quot;&lt;/span&gt;

&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; Map.fromList [(&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;world&amp;quot;&lt;/span&gt;]) &lt;span class=&#34;fu&#34;&gt;&amp;amp;&lt;/span&gt; at &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;.~&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Nothing&lt;/span&gt;
fromList []

&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; Map.fromList [(&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;world&amp;quot;&lt;/span&gt;]) &lt;span class=&#34;fu&#34;&gt;&amp;amp;&lt;/span&gt; at &lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;.~&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Just&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;hi&amp;quot;&lt;/span&gt;
fromList [(&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;world&amp;quot;&lt;/span&gt;), (&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;hi&amp;quot;&lt;/span&gt;)]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;ix&lt;/code&gt; – a traversal for “element-at-index”; similar to &lt;code&gt;at&lt;/code&gt;, but can&#39;t be used for inserting/deleting elements and works with more things (e.g. lists and vectors).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;_head&lt;/code&gt;, &lt;code&gt;_tail&lt;/code&gt;, &lt;code&gt;_init&lt;/code&gt;, &lt;code&gt;_last&lt;/code&gt; – traversals for first/last element (and init/tail) of various structures (like &lt;code&gt;ix&lt;/code&gt;, they are overloaded)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;folded&lt;/code&gt; – a getter for anything &lt;code&gt;Foldable&lt;/code&gt;; &lt;code&gt;mapped&lt;/code&gt; – a setter for any &lt;code&gt;Functor&lt;/code&gt;; &lt;code&gt;traversed&lt;/code&gt; – a traversal for any &lt;code&gt;Traversable&lt;/code&gt; (but in many cases &lt;code&gt;each&lt;/code&gt; is going to work as well).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;filtered&lt;/code&gt; – a traversal that traverses an element only if it satisfies a predicate:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; (&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;4&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;) &lt;span class=&#34;fu&#34;&gt;^..&lt;/span&gt; each &lt;span class=&#34;fu&#34;&gt;.&lt;/span&gt; filtered even
[&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;4&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can &lt;em&gt;use&lt;/em&gt; it for setting/modifying too, but if you&#39;re going to use it to define other traversals, read &lt;a href=&#34;https://hackage.haskell.org/package/microlens/docs/Lens-Micro.html#v:filtered&#34;&gt;this&lt;/a&gt; first because you might get bitten otherwise.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;_Left&lt;/code&gt;, &lt;code&gt;_Right&lt;/code&gt;, &lt;code&gt;_Just&lt;/code&gt;, &lt;code&gt;_Nothing&lt;/code&gt; – prisms for accessing branches of &lt;code&gt;Either&lt;/code&gt; and &lt;code&gt;Maybe&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;worded&lt;/code&gt; and &lt;code&gt;lined&lt;/code&gt; – traversals for words/lines in a string.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;strict&lt;/code&gt;, &lt;code&gt;lazy&lt;/code&gt; – &lt;code&gt;Iso&lt;/code&gt;s for converting &lt;code&gt;Text&lt;/code&gt;/&lt;code&gt;ByteString&lt;/code&gt; from lazy to strict or vice-versa.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-ov2yi6mf-writing-your-own-lenses&#34;&gt;&lt;/span&gt;Writing your own lenses&lt;/h1&gt;&lt;p&gt;You can use &lt;code&gt;lens&lt;/code&gt;, &lt;code&gt;prism&lt;/code&gt;, &lt;code&gt;iso&lt;/code&gt;, &lt;code&gt;setting&lt;/code&gt; &lt;code&gt;folding&lt;/code&gt;, or &lt;code&gt;to&lt;/code&gt; (for getters) to create a lens/prism/etc out of a getter and a setter. You can also easily write lenses and traversals manually:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Lens&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;ot&#34;&gt;_1 ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Lens&lt;/span&gt; (a, x) (b, x) a b
_1 f &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; \(a, x) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; (,x) &lt;span class=&#34;fu&#34;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; f b&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Traversal&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;ot&#34;&gt;both ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Traversal&#39;&lt;/span&gt; (a, a) a
both f &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; \(a1, a2) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; (,) &lt;span class=&#34;fu&#34;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; f a1 &lt;span class=&#34;fu&#34;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; f a2

&lt;span class=&#34;ot&#34;&gt;_head ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Traversal&#39;&lt;/span&gt; [a] a
_head f   []   &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; pure []
_head f (x&lt;span class=&#34;fu&#34;&gt;:&lt;/span&gt;xs) &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; (&lt;span class=&#34;fu&#34;&gt;:&lt;/span&gt;xs) &lt;span class=&#34;fu&#34;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; f x&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-ov2yi6mf-of-functions&#34;&gt;&lt;/span&gt;&lt;code&gt;*Of&lt;/code&gt; functions&lt;/h1&gt;&lt;p&gt;Many functions from base have their &lt;code&gt;*Of&lt;/code&gt; counterparts in lens. When a function traverses something, its &lt;code&gt;*Of&lt;/code&gt; counterpart traverses something using the traversal you give to it.&lt;/p&gt;
&lt;p&gt;Are there any even elements in a tuple?&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; anyOf each even (&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;)
&lt;span class=&#34;dt&#34;&gt;True&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;How many elements are in a list of lists?&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; lengthOf (each&lt;span class=&#34;fu&#34;&gt;.&lt;/span&gt;each) [[&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;],[&lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;4&lt;/span&gt;],[&lt;span class=&#34;dv&#34;&gt;5&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;6&lt;/span&gt;]]
&lt;span class=&#34;dv&#34;&gt;6&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;How many elements are equal to their index?&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; length &lt;span class=&#34;fu&#34;&gt;.&lt;/span&gt; filter (\(i, x) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; i &lt;span class=&#34;fu&#34;&gt;==&lt;/span&gt; x) &lt;span class=&#34;fu&#34;&gt;.&lt;/span&gt; zip [&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;..&lt;/span&gt;] &lt;span class=&#34;fu&#34;&gt;$&lt;/span&gt; [&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;,&lt;span class=&#34;fu&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;,&lt;span class=&#34;fu&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;]
&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;

&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; lengthOf (traversed&lt;span class=&#34;fu&#34;&gt;.&lt;/span&gt;ifiltered (&lt;span class=&#34;fu&#34;&gt;==&lt;/span&gt;)) [&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;,&lt;span class=&#34;fu&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;,&lt;span class=&#34;fu&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;]
&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-ov2yi6mf-indexed-traversals&#34;&gt;&lt;/span&gt;Indexed traversals&lt;/h1&gt;&lt;p&gt;An indexed traversal is a traversal that gives the index of the traversed element to the function. Indexed traversals can be used like ordinary traversals too, thanks to some &lt;a href=&#34;https://hackage.haskell.org/package/lens/docs/Control-Lens-Internal-Indexed.html#t:Conjoined&#34;&gt;horrible magic&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Most of the time you can make an indexed operator of an ordinary one by adding &lt;code&gt;@&lt;/code&gt; to it, or an indexed function out of ordinary one by sticking &lt;code&gt;i&lt;/code&gt; in front of it. A lot of standard traversals are already indexed (e.g. &lt;code&gt;traversed&lt;/code&gt;). For instance, here we multiply each element in the list by its index:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; [&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;4&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;] &lt;span class=&#34;fu&#34;&gt;&amp;amp;&lt;/span&gt; traversed &lt;span class=&#34;fu&#34;&gt;%@~&lt;/span&gt; (\i x &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; (i&lt;span class=&#34;fu&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;) &lt;span class=&#34;fu&#34;&gt;*&lt;/span&gt; x)
[&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;8&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;6&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;12&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;5&lt;/span&gt;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(&lt;code&gt;each&lt;/code&gt; isn&#39;t an indexed traversal, but you can use e.g. &lt;code&gt;Data.Text.Lens.text&lt;/code&gt; and &lt;code&gt;Data.ByteString.Lens.bytes&lt;/code&gt; for &lt;code&gt;Text&lt;/code&gt; and &lt;code&gt;ByteString&lt;/code&gt; respectively.)&lt;/p&gt;
&lt;p&gt;A lot of functions from base have their indexed counterparts in lens. For instance, you can use &lt;code&gt;iany&lt;/code&gt; to check whether any element in the list is equal to its index, and &lt;code&gt;ifind&lt;/code&gt; to actually find that element:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; iany (&lt;span class=&#34;fu&#34;&gt;==&lt;/span&gt;) [&lt;span class=&#34;dv&#34;&gt;4&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;]
&lt;span class=&#34;dt&#34;&gt;True&lt;/span&gt;

&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; ifind (&lt;span class=&#34;fu&#34;&gt;==&lt;/span&gt;) [&lt;span class=&#34;dv&#34;&gt;4&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;]
&lt;span class=&#34;dt&#34;&gt;Just&lt;/span&gt; (&lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can combine &lt;code&gt;indices&lt;/code&gt; with another traversal to only traverse elements with index satisfying some condition:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; over (traversed&lt;span class=&#34;fu&#34;&gt;.&lt;/span&gt;indices (&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;)) reverse [&lt;span class=&#34;st&#34;&gt;&amp;quot;He&amp;quot;&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;was&amp;quot;&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;stressed&amp;quot;&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;o_O&amp;quot;&lt;/span&gt;]
[&lt;span class=&#34;st&#34;&gt;&amp;quot;He&amp;quot;&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;saw&amp;quot;&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;desserts&amp;quot;&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;O_o&amp;quot;&lt;/span&gt;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When you compose indexed traversals, by default the index from the right traversal is retained:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; [&lt;span class=&#34;st&#34;&gt;&amp;quot;abcd&amp;quot;&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;efgh&amp;quot;&lt;/span&gt;] &lt;span class=&#34;fu&#34;&gt;^@..&lt;/span&gt; traversed&lt;span class=&#34;fu&#34;&gt;.&lt;/span&gt;traversed
[(&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;,&lt;span class=&#34;ch&#34;&gt;&#39;a&#39;&lt;/span&gt;),(&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;ch&#34;&gt;&#39;b&#39;&lt;/span&gt;),(&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;,&lt;span class=&#34;ch&#34;&gt;&#39;c&#39;&lt;/span&gt;),(&lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;,&lt;span class=&#34;ch&#34;&gt;&#39;d&#39;&lt;/span&gt;),
 (&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;,&lt;span class=&#34;ch&#34;&gt;&#39;e&#39;&lt;/span&gt;),(&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;ch&#34;&gt;&#39;f&#39;&lt;/span&gt;),(&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;,&lt;span class=&#34;ch&#34;&gt;&#39;g&#39;&lt;/span&gt;),(&lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;,&lt;span class=&#34;ch&#34;&gt;&#39;h&#39;&lt;/span&gt;)]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can use &lt;code&gt;&amp;lt;.&lt;/code&gt; to retain the index from the left traversal:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; [&lt;span class=&#34;st&#34;&gt;&amp;quot;abcd&amp;quot;&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;efgh&amp;quot;&lt;/span&gt;] &lt;span class=&#34;fu&#34;&gt;^@..&lt;/span&gt; traversed&lt;span class=&#34;fu&#34;&gt;&amp;lt;.&lt;/span&gt;traversed
[(&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;,&lt;span class=&#34;ch&#34;&gt;&#39;a&#39;&lt;/span&gt;),(&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;,&lt;span class=&#34;ch&#34;&gt;&#39;b&#39;&lt;/span&gt;),(&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;,&lt;span class=&#34;ch&#34;&gt;&#39;c&#39;&lt;/span&gt;),(&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;,&lt;span class=&#34;ch&#34;&gt;&#39;d&#39;&lt;/span&gt;),
 (&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;ch&#34;&gt;&#39;e&#39;&lt;/span&gt;),(&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;ch&#34;&gt;&#39;f&#39;&lt;/span&gt;),(&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;ch&#34;&gt;&#39;g&#39;&lt;/span&gt;),(&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;ch&#34;&gt;&#39;h&#39;&lt;/span&gt;)]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or you can use &lt;code&gt;&amp;lt;.&amp;gt;&lt;/code&gt; to combine both indexes into a tuple:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; [&lt;span class=&#34;st&#34;&gt;&amp;quot;abcd&amp;quot;&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;efgh&amp;quot;&lt;/span&gt;] &lt;span class=&#34;fu&#34;&gt;^@..&lt;/span&gt; traversed&lt;span class=&#34;fu&#34;&gt;&amp;lt;.&amp;gt;&lt;/span&gt;traversed
[((&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;),&lt;span class=&#34;ch&#34;&gt;&#39;a&#39;&lt;/span&gt;),((&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;),&lt;span class=&#34;ch&#34;&gt;&#39;b&#39;&lt;/span&gt;),((&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;),&lt;span class=&#34;ch&#34;&gt;&#39;c&#39;&lt;/span&gt;),((&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;),&lt;span class=&#34;ch&#34;&gt;&#39;d&#39;&lt;/span&gt;),
 ((&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;),&lt;span class=&#34;ch&#34;&gt;&#39;e&#39;&lt;/span&gt;),((&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;),&lt;span class=&#34;ch&#34;&gt;&#39;f&#39;&lt;/span&gt;),((&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;),&lt;span class=&#34;ch&#34;&gt;&#39;g&#39;&lt;/span&gt;),((&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;),&lt;span class=&#34;ch&#34;&gt;&#39;h&#39;&lt;/span&gt;)]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For some types, several variants of indexing are possible – for instance, when you&#39;re traversing a &lt;code&gt;Map k v&lt;/code&gt;, you could say that the index should be &lt;code&gt;k&lt;/code&gt; (i.e. the element&#39;s key), or &lt;code&gt;Int&lt;/code&gt; (i.e. the order in which it was traversed). &lt;code&gt;itraversed&lt;/code&gt; gives you the former, and &lt;code&gt;traversed&lt;/code&gt; gives you the latter:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;let&lt;/span&gt; m &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; Map.fromList [(&lt;span class=&#34;st&#34;&gt;&amp;quot;John&amp;quot;&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;Doe&amp;quot;&lt;/span&gt;), (&lt;span class=&#34;st&#34;&gt;&amp;quot;Jane&amp;quot;&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;Roe&amp;quot;&lt;/span&gt;)]

&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; m &lt;span class=&#34;fu&#34;&gt;^@..&lt;/span&gt; traversed
[(&lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;Roe&amp;quot;&lt;/span&gt;),(&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;Doe&amp;quot;&lt;/span&gt;)]

&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; m &lt;span class=&#34;fu&#34;&gt;^@..&lt;/span&gt; itraversed
[(&lt;span class=&#34;st&#34;&gt;&amp;quot;Jane&amp;quot;&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;Roe&amp;quot;&lt;/span&gt;),(&lt;span class=&#34;st&#34;&gt;&amp;quot;John&amp;quot;&lt;/span&gt;,&lt;span class=&#34;st&#34;&gt;&amp;quot;Doe&amp;quot;&lt;/span&gt;)]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;indexing&lt;/code&gt; can turn any traversal into an indexed traversal, and &lt;code&gt;indexed64&lt;/code&gt; does the same but uses &lt;code&gt;Int64&lt;/code&gt; as the index (in case your structure is really big).&lt;/p&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-ov2yi6mf-common-gotchas&#34;&gt;&lt;/span&gt;Common gotchas&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;weird error messages about &lt;code&gt;Monoid&lt;/code&gt; usually appear when you try to use &lt;code&gt;^.&lt;/code&gt; on a traversal&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;can&#39;t &lt;a href=&#34;https://github.com/ekmett/lens/issues/109&#34;&gt;combine traversals vertically&lt;/a&gt; (e.g. can&#39;t take &lt;code&gt;_1&lt;/code&gt; and &lt;code&gt;_3&lt;/code&gt; and make a traversal that traverses the 1st and 3rd elements of a tuple)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;if you want to make a list of lenses or store a lens in a record, you have to use &lt;code&gt;ALens&lt;/code&gt; instead of &lt;code&gt;Lens&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-ov2yi6mf-todo&#34;&gt;&lt;/span&gt;TODO&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;write about using lenses &lt;a href=&#34;http://www.haskellforall.com/2013/05/program-imperatively-using-haskell.html&#34;&gt;with state&lt;/a&gt; and reader&lt;/li&gt;
&lt;li&gt;mention pattern synonyms&lt;/li&gt;
&lt;li&gt;mention &lt;code&gt;^?&lt;/code&gt;, &lt;code&gt;^?!&lt;/code&gt;, &lt;code&gt;singular&lt;/code&gt;, &lt;code&gt;has&lt;/code&gt;, etc etc etc&lt;/li&gt;
&lt;li&gt;combining folds with &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; – &lt;code&gt;x ^.. (a &amp;lt;&amp;gt; b)&lt;/code&gt; is the same as &lt;code&gt;(x ^.. a) ++ (x ^.. b)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/lenses-sth6l9jl#item-ov2yi6mf"/></entry><entry><id>nio0v3br</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">fclabels</title><updated>2016-03-10T11:06:40Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;fclabels&lt;/span&gt;

  
  (&lt;a href=&#34;https://hackage.haskell.org/package/fclabels&#34;&gt;Hackage&lt;/a&gt;)
&lt;/h1&gt;&lt;p&gt;A do-it-yourself lens library that doesn&#39;t try to be a universal data manipulation toolkit – if you don&#39;t need such a toolkit, and if you want monadic lenses, it could be useful.&lt;/p&gt;
&lt;h2&gt;Pros&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;Few dependencies (compared to lens).&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Has lenses that can report errors (via &lt;code&gt;Either&lt;/code&gt;).&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Has monadic lenses (e.g. you could make a lens that reads a file, or an &lt;code&gt;IORef&lt;/code&gt;, or something from a database).&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Lets you compose lenses into bigger lenses (a pretty unique feature among lens libraries – all other libraries require you to write lenses manually or provide a getter and a setter).&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Can make lenses for GADTs (see an example in the notes).&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Cons&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;Doesn&#39;t have traversals at all. (Apart from “partial lenses” like &lt;code&gt;just&lt;/code&gt;.)&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Provides &lt;a href=&#34;https://hackage.haskell.org/package/fclabels/docs/Data-Label-Base.html&#34;&gt;very few&lt;/a&gt; lenses.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Is designed to be imported qualified (which can be annoying), and you have to &lt;code&gt;import Prelude hiding (id, (.))&lt;/code&gt; as well if you want to use it.&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Ecosystem&lt;/h2&gt;&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/fclabels-monadlib&#34;&gt;fclabels-monadlib&lt;/a&gt;, &lt;a href=&#34;https://hackage.haskell.org/package/lens-sop&#34;&gt;lens-sop&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Notes&lt;/h2&gt;&lt;h1&gt;&lt;span id=&#34;item-notes-nio0v3br-links&#34;&gt;&lt;/span&gt;Links&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://fvisser.nl/post/2013/okt/1/fclabels-2.0.html&#34;&gt;a tutorial&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-nio0v3br-imports&#34;&gt;&lt;/span&gt;Imports&lt;/h1&gt;&lt;p&gt;The default is total lenses that can&#39;t change the type of the value (they are called &lt;code&gt;:-&amp;gt;&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;ot&#34;&gt;{-# LANGUAGE TypeOperators #-}&lt;/span&gt;

&lt;span class=&#34;kw&#34;&gt;import &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Data.Label&lt;/span&gt; ((:-&amp;gt;))
&lt;span class=&#34;kw&#34;&gt;import qualified&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Data.Label&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;L&lt;/span&gt;
&lt;span class=&#34;co&#34;&gt;-- for predefined lenses&lt;/span&gt;
&lt;span class=&#34;kw&#34;&gt;import qualified&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Data.Label.Base&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;L&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-nio0v3br-gadts&#34;&gt;&lt;/span&gt;GADTs&lt;/h1&gt;&lt;p&gt;This works with fclabels and silently fails with lens:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;ot&#34;&gt;{-# LANGUAGE GADTs, TemplateHaskell #-}&lt;/span&gt;

&lt;span class=&#34;kw&#34;&gt;import qualified&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Data.Label&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;L&lt;/span&gt;

&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;X&lt;/span&gt; a &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;
  &lt;span class=&#34;dt&#34;&gt;X&lt;/span&gt;&lt;span class=&#34;ot&#34;&gt; ::&lt;/span&gt; {&lt;span class=&#34;ot&#34;&gt;_a ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;} &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;X&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Bool&lt;/span&gt;

L.mkLabel &lt;span class=&#34;ch&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;X&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-nio0v3br-constructing-lenses-out-of-smaller-lenses&#34;&gt;&lt;/span&gt;Constructing lenses out of smaller lenses&lt;/h1&gt;&lt;p&gt;fclabels has operators that let you create “views” into structures, which could be useful if e.g. you have fields that are related, but not related enough to move them out into their own datatype. Here&#39;s a (somewhat contrived) example.&lt;/p&gt;
&lt;p&gt;First, some prerequisites:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;ot&#34;&gt;{-# LANGUAGE TypeOperators, TemplateHaskell #-}&lt;/span&gt;

&lt;span class=&#34;kw&#34;&gt;import &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Data.Label&lt;/span&gt; ((:-&amp;gt;), (&amp;gt;-))
&lt;span class=&#34;kw&#34;&gt;import qualified&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Data.Label&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;L&lt;/span&gt;
&lt;span class=&#34;kw&#34;&gt;import &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Prelude&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;hiding&lt;/span&gt; (id, (.))
&lt;span class=&#34;kw&#34;&gt;import &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Control.Category&lt;/span&gt; (id, (.))

&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Person&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Person&lt;/span&gt;
  {&lt;span class=&#34;ot&#34;&gt; _name   ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;
  ,&lt;span class=&#34;ot&#34;&gt; _age    ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt;
  ,&lt;span class=&#34;ot&#34;&gt; _place  ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Place&lt;/span&gt;
  } &lt;span class=&#34;kw&#34;&gt;deriving&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Show&lt;/span&gt;

&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Place&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Place&lt;/span&gt;
  { _city
  , _country
  ,&lt;span class=&#34;ot&#34;&gt; _continent ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;
  } &lt;span class=&#34;kw&#34;&gt;deriving&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Show&lt;/span&gt;

L.mkLabels [&lt;span class=&#34;ch&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Person&lt;/span&gt;, &lt;span class=&#34;ch&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Place&lt;/span&gt;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And the view itself:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;ot&#34;&gt;ageAndCity ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Person&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;:-&amp;gt;&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt;, &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;)
ageAndCity &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; L.point &lt;span class=&#34;fu&#34;&gt;$&lt;/span&gt;
  (,) &lt;span class=&#34;fu&#34;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; L.fst &lt;span class=&#34;fu&#34;&gt;&amp;gt;-&lt;/span&gt; age
      &lt;span class=&#34;fu&#34;&gt;&amp;lt;*&amp;gt;&lt;/span&gt; L.snd &lt;span class=&#34;fu&#34;&gt;&amp;gt;-&lt;/span&gt; city &lt;span class=&#34;fu&#34;&gt;.&lt;/span&gt; place&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(Of course, instead of &lt;code&gt;(,)&lt;/code&gt; you could use any other data constructor.)&lt;/p&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-nio0v3br-monadic-lenses&#34;&gt;&lt;/span&gt;Monadic lenses&lt;/h1&gt;&lt;p&gt;fclabels lets you define lenses that work in some monad. For instance, partial lenses (here &lt;code&gt;f&lt;/code&gt; is the outer type and &lt;code&gt;o&lt;/code&gt; is the inner type):&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; (&lt;span class=&#34;fu&#34;&gt;:~&amp;gt;&lt;/span&gt;) f o &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Poly.Lens&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Kleisli&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Maybe&lt;/span&gt;) f o&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And lenses that work in &lt;code&gt;Either&lt;/code&gt; and can report errors (and e.g. validate the value you&#39;re trying to set before setting it):&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Lens&lt;/span&gt; e f o &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Poly.Lens&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Kleisli&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Either&lt;/span&gt; e)) f o&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Similarly we could define a type for lenses that have access to IO:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;ot&#34;&gt;{-# LANGUAGE TupleSections #-}&lt;/span&gt;

&lt;span class=&#34;kw&#34;&gt;import qualified&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Data.Label.Poly&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Poly&lt;/span&gt;
&lt;span class=&#34;kw&#34;&gt;import qualified&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Data.Label.Mono&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Mono&lt;/span&gt;

&lt;span class=&#34;kw&#34;&gt;import &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Control.Arrow&lt;/span&gt;
&lt;span class=&#34;kw&#34;&gt;import &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Control.Exception&lt;/span&gt; (evaluate)
&lt;span class=&#34;kw&#34;&gt;import &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Control.Category&lt;/span&gt; ((.), id)
&lt;span class=&#34;kw&#34;&gt;import &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Prelude&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;hiding&lt;/span&gt; ((.), id)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;co&#34;&gt;-- The type&lt;/span&gt;
&lt;span class=&#34;kw&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IOLens&lt;/span&gt; f o &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Mono.Lens&lt;/span&gt; (&lt;span class=&#34;dt&#34;&gt;Kleisli&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IO&lt;/span&gt;) f o&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;co&#34;&gt;-- Functions for getting/setting/modifying (for some reason you have to&lt;/span&gt;
&lt;span class=&#34;co&#34;&gt;-- define them manually – I stole the definitions from Data.Label.Failing&lt;/span&gt;
&lt;span class=&#34;co&#34;&gt;-- and changed the types)&lt;/span&gt;

&lt;span class=&#34;ot&#34;&gt;get ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IOLens&lt;/span&gt; s a &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; s &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IO&lt;/span&gt; a
get l &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; runKleisli (Poly.get l)

&lt;span class=&#34;ot&#34;&gt;set ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IOLens&lt;/span&gt; s a &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; a &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; s &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IO&lt;/span&gt; s
set l v &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; runKleisli (Poly.set l &lt;span class=&#34;fu&#34;&gt;.&lt;/span&gt; arr (v,))

&lt;span class=&#34;ot&#34;&gt;modify ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IOLens&lt;/span&gt; s a &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; (a &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; a) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; s &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IO&lt;/span&gt; s
modify l m &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; runKleisli (Poly.modify l &lt;span class=&#34;fu&#34;&gt;.&lt;/span&gt; arr (arr m,))&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;co&#34;&gt;-- A function to create a lens from a getter and a setter&lt;/span&gt;
&lt;span class=&#34;ot&#34;&gt;lens ::&lt;/span&gt; (f &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IO&lt;/span&gt; o)
     &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; ((o &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IO&lt;/span&gt; o) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; f &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IO&lt;/span&gt; f)
     &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IOLens&lt;/span&gt; f o
lens g s &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; Poly.lens (&lt;span class=&#34;dt&#34;&gt;Kleisli&lt;/span&gt; g) (&lt;span class=&#34;dt&#34;&gt;Kleisli&lt;/span&gt; (\(m, f) &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; s (runKleisli m) f))&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;co&#34;&gt;-- And, finally, the lens itself&lt;/span&gt;
&lt;span class=&#34;ot&#34;&gt;file ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;IOLens&lt;/span&gt; FilePath &lt;span class=&#34;dt&#34;&gt;String&lt;/span&gt;
file &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; lens readFile setter
  &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;
    &lt;span class=&#34;co&#34;&gt;-- f :: String -&amp;gt; IO String&lt;/span&gt;
    setter f path &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;
      x &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; readFile path
      evaluate (length x)    &lt;span class=&#34;co&#34;&gt;-- force the file to be read fully&lt;/span&gt;
      writeFile path &lt;span class=&#34;fu&#34;&gt;=&amp;lt;&amp;lt;&lt;/span&gt; f x
      return path&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/lenses-sth6l9jl#item-nio0v3br"/></entry><entry><id>hhjytv4g</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">lens-simple</title><updated>2016-03-10T11:06:40Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;lens-simple&lt;/span&gt;

  
  (&lt;a href=&#34;https://hackage.haskell.org/package/lens-simple&#34;&gt;Hackage&lt;/a&gt;)
&lt;/h1&gt;&lt;p&gt;Another small lens-compatible library. Has a simpler implementation, which is good for learning. Doesn&#39;t have good docs, which is bad for learning.&lt;/p&gt;
&lt;h2&gt;Pros&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;Rather small, has few dependencies.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Unlike microlens, has &lt;code&gt;*Of&lt;/code&gt; functions and many operators from lens (&lt;code&gt;&amp;lt;&amp;gt;~&lt;/code&gt;, &lt;code&gt;&amp;amp;&amp;amp;=&lt;/code&gt;, etc).&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;The implementation is simpler than that of either lens or microlens (so it could be good for studying how lenses work).&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Cons&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;Doesn&#39;t use overloading, so &lt;code&gt;_1&lt;/code&gt; and &lt;code&gt;_2&lt;/code&gt; only work on pairs, &lt;code&gt;ix&lt;/code&gt; doesn&#39;t work with lists, and &lt;code&gt;at&lt;/code&gt; only works with &lt;code&gt;Map&lt;/code&gt;. If you try to use it for a big project, you might end up annoyed with missing functionality.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Doesn&#39;t provide lens&#39;s more advanced features (like prisms or indexed traversals).&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Its &lt;code&gt;Fold&lt;/code&gt; can&#39;t be used by functions from lens that take a &lt;code&gt;Fold&lt;/code&gt; from lens, which potentially hurts compatibility a bit.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Could be slower than lens (due to the absence of &lt;code&gt;INLINE&lt;/code&gt; pragmas – but I haven&#39;t benchmarked).&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Notes&lt;/h2&gt;&lt;h1&gt;&lt;span id=&#34;item-notes-hhjytv4g-imports&#34;&gt;&lt;/span&gt;Imports&lt;/h1&gt;&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;kw&#34;&gt;import &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Lens.Simple&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-hhjytv4g-usage&#34;&gt;&lt;/span&gt;Usage&lt;/h1&gt;&lt;p&gt;See notes for lens.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/lenses-sth6l9jl#item-hhjytv4g"/></entry><entry><id>gk4o90sk</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">microlens</title><updated>2016-03-10T11:06:40Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;a href=&#34;https://github.com/aelve/microlens&#34; class=&#34;item-name&#34;&gt;microlens&lt;/a&gt;

  
  (&lt;a href=&#34;https://hackage.haskell.org/package/microlens&#34;&gt;Hackage&lt;/a&gt;)
&lt;/h1&gt;&lt;p&gt;A fork of &lt;a href=&#34;https://hackage.haskell.org/package/lens&#34;&gt;lens&lt;/a&gt; that explicitly tries to be as small as possible while still being useful (e.g. all extra features are split into separate packages). Provides a somewhat different set of functions than &lt;a href=&#34;https://hackage.haskell.org/package/lens-simple&#34;&gt;lens-simple&lt;/a&gt;, but generally is closer to lens than lens-simple is. Like lens, uses ad-hoc typeclasses to provide overloaded lenses.&lt;/p&gt;
&lt;h2&gt;Pros&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;Very small (the base package has no dependencies at all).&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Has better documentation than either lens-simple or lens.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;It&#39;s just a fork of lens, so nothing has been renamed and everything behaves in the same way. (And also it should be just as fast.)&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Doesn&#39;t omit overloaded lenses (so &lt;code&gt;at&lt;/code&gt; and &lt;code&gt;_1&lt;/code&gt; work with many things) – and it also provides &lt;code&gt;each&lt;/code&gt;, a traversal that can traverse mostly everything.&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Cons&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;Doesn&#39;t provide lens&#39;s more advanced features (like prisms or indexed traversals).&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Doesn&#39;t let you write code in fully “lensy” style (since it omits lots of operators and &lt;code&gt;*Of&lt;/code&gt; functions from lens).&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Provides orphan instances in &lt;a href=&#34;https://hackage.haskell.org/package/microlens-ghc&#34;&gt;microlens-ghc&lt;/a&gt; and &lt;a href=&#34;https://hackage.haskell.org/package/microlens-platform&#34;&gt;microlens-platform&lt;/a&gt;.&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Ecosystem&lt;/h2&gt;&lt;p&gt;Official:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://hackage.haskell.org/package/microlens-th&#34;&gt;microlens-th&lt;/a&gt; for automatic lens generation&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://hackage.haskell.org/package/microlens-mtl&#34;&gt;microlens-mtl&lt;/a&gt; with &lt;a href=&#34;https://hackage.haskell.org/package/mtl&#34;&gt;mtl&lt;/a&gt;-related things like &lt;code&gt;zoom&lt;/code&gt; and &lt;code&gt;.=&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://hackage.haskell.org/package/microlens-ghc&#34;&gt;microlens-ghc&lt;/a&gt; (instances for libraries shipped with GHC)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://hackage.haskell.org/package/microlens-platform&#34;&gt;microlens-platform&lt;/a&gt; (instances for &lt;a href=&#34;https://hackage.haskell.org/package/vector&#34;&gt;vector&lt;/a&gt;, &lt;a href=&#34;https://hackage.haskell.org/package/text&#34;&gt;text&lt;/a&gt;, etc)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://hackage.haskell.org/package/microlens-contra&#34;&gt;microlens-contra&lt;/a&gt; – true &lt;code&gt;Getter&lt;/code&gt; and &lt;code&gt;Fold&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Unofficial:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://hackage.haskell.org/package/microlens-aeson&#34;&gt;microlens-aeson&lt;/a&gt; – lenses for &lt;a href=&#34;https://hackage.haskell.org/package/aeson&#34;&gt;aeson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://hackage.haskell.org/package/zlib-lens&#34;&gt;zlib-lens&lt;/a&gt; – not made for microlens but can be used with it&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Notes&lt;/h2&gt;&lt;h1&gt;&lt;span id=&#34;item-notes-gk4o90sk-imports&#34;&gt;&lt;/span&gt;Imports&lt;/h1&gt;&lt;p&gt;If importing everything separately is annoying to you, &lt;code&gt;Lens.Micro.Platform&lt;/code&gt; from &lt;a href=&#34;https://hackage.haskell.org/package/microlens-platform&#34;&gt;microlens-platform&lt;/a&gt; reexports functions from all other packages (together with instances for &lt;code&gt;HashMap&lt;/code&gt;, &lt;code&gt;Vector&lt;/code&gt;, etc). Otherwise:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Lens.Micro&lt;/code&gt; exports most things&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Lens.Micro.TH&lt;/code&gt; from &lt;a href=&#34;https://hackage.haskell.org/package/microlens-th&#34;&gt;microlens-th&lt;/a&gt; exports &lt;code&gt;makeLenses&lt;/code&gt; and so on&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Lens.Micro.Mtl&lt;/code&gt; from &lt;a href=&#34;https://hackage.haskell.org/package/microlens-mtl&#34;&gt;microlens-mtl&lt;/a&gt; exports &lt;code&gt;view&lt;/code&gt;/&lt;code&gt;use&lt;/code&gt;, &lt;code&gt;.=&lt;/code&gt;/&lt;code&gt;%=&lt;/code&gt;/etc, and &lt;code&gt;zoom&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-gk4o90sk-usage&#34;&gt;&lt;/span&gt;Usage&lt;/h1&gt;&lt;p&gt;See notes for lens.&lt;/p&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-gk4o90sk-gotchas&#34;&gt;&lt;/span&gt;Gotchas&lt;/h1&gt;&lt;p&gt;If you&#39;re looking for &lt;code&gt;view&lt;/code&gt;: it&#39;s not in &lt;code&gt;Lens.Micro&lt;/code&gt;. Either do &lt;code&gt;import Lens.Micro.Extras (view)&lt;/code&gt; or use microlens-platform. Same goes for &lt;code&gt;preview&lt;/code&gt;.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/lenses-sth6l9jl#item-gk4o90sk"/></entry><entry><id>a03s8oxx</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">data-lens-light</title><updated>2016-03-10T11:06:40Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;data-lens-light&lt;/span&gt;

  
  (&lt;a href=&#34;https://hackage.haskell.org/package/data-lens-light&#34;&gt;Hackage&lt;/a&gt;)
&lt;/h1&gt;&lt;p&gt;A really really basic lenses library that only seems to be useful for record manipulation.&lt;/p&gt;
&lt;h2&gt;Pros&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;Has the most obvious implementation – &lt;code&gt;Lens a b = a -&amp;gt; (b -&amp;gt; a, b)&lt;/code&gt; – without any tricks or weird typeclasses or anything.&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Cons&lt;/h2&gt;&lt;ul&gt;&lt;p&gt;&lt;li&gt;Lets you make and use lenses, but doesn&#39;t actually give any lenses, so you have to define them by yourself (or use Template Haskell generation).&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;No traversals, no prisms, nothing.&lt;/li&gt;&lt;/p&gt;&lt;p&gt;&lt;li&gt;Doesn&#39;t allow lenses that change the type.&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;h2&gt;Ecosystem&lt;/h2&gt;&lt;p&gt;&lt;a href=&#34;https://hackage.haskell.org/package/time-lens&#34;&gt;time-lens&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Notes&lt;/h2&gt;&lt;h1&gt;&lt;span id=&#34;item-notes-a03s8oxx-imports&#34;&gt;&lt;/span&gt;Imports&lt;/h1&gt;&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;kw&#34;&gt;import &lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Data.Lens.Light&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span id=&#34;item-notes-a03s8oxx-usage&#34;&gt;&lt;/span&gt;Usage&lt;/h1&gt;&lt;p&gt;First let&#39;s define some lenses for tuples (to use them as examples):&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;ot&#34;&gt;fstL ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Lens&lt;/span&gt; (a, b) a
fstL &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; lens fst (\(a, _) b &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; (a, b))

&lt;span class=&#34;ot&#34;&gt;swapL ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Lens&lt;/span&gt; (a, b) (b, a)
swapL &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; iso swap swap
  &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt; swap (x, y) &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; (y, x)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Getting/setting/modifying:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode repl&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; getL fstL (&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;)
&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;

&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; setL fstL &lt;span class=&#34;dv&#34;&gt;10&lt;/span&gt; (&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;)
(&lt;span class=&#34;dv&#34;&gt;10&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;)

&lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; modL fstL negate (&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;)
(&lt;span class=&#34;fu&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;,&lt;span class=&#34;dv&#34;&gt;2&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Generating lenses with TH:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;ot&#34;&gt;{-# LANGUAGE TemplateHaskell #-}&lt;/span&gt;

&lt;span class=&#34;kw&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Score&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Score&lt;/span&gt; { 
&lt;span class=&#34;ot&#34;&gt;  _p1Score ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt;,
&lt;span class=&#34;ot&#34;&gt;  _p2Score ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt;,
&lt;span class=&#34;ot&#34;&gt;  rounds ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; }

makeLenses &lt;span class=&#34;ch&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;dt&#34;&gt;Score&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/lenses-sth6l9jl#item-a03s8oxx"/></entry></feed>