<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Comonad.Reader &#187; Lenses</title>
	<atom:link href="http://comonad.com/reader/category/lenses/feed/" rel="self" type="application/rss+xml" />
	<link>http://comonad.com/reader</link>
	<description>types, (co)monads, substructural logic</description>
	<lastBuildDate>Mon, 24 Oct 2022 17:48:27 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Japanese &#8220;ekmett&#8221; Workshop (Part 1 of 2)</title>
		<link>http://comonad.com/reader/2013/japanese-workshop-1/</link>
		<comments>http://comonad.com/reader/2013/japanese-workshop-1/#comments</comments>
		<pubDate>Mon, 01 Apr 2013 05:59:05 +0000</pubDate>
		<dc:creator>Edward Kmett</dc:creator>
				<category><![CDATA[Japan]]></category>
		<category><![CDATA[Lenses]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[workshop]]></category>

		<guid isPermaLink="false">http://comonad.com/reader/?p=831</guid>
		<description><![CDATA[A couple of weeks back one of my coworkers brought to my attention a several hour long workshop in Japan to go over and describe a number of my libraries, hosted by TANAKA Hideyuki — not the voice actor, I checked!
I was incredibly honored and I figured that if that many people (they had 30 [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of weeks back one of my coworkers brought to my attention <a href="http://partake.in/events/1698f7f8-4151-4048-b317-03a8c3f1a7ab">a several hour long workshop in Japan</a> to go over and describe a number of my libraries, hosted by <a href="https://github.com/tanakh">TANAKA Hideyuki</a> — not the <a href="http://en.wikipedia.org/wiki/Hideyuki_Tanaka">voice actor</a>, I checked!</p>
<p>I was incredibly honored and I figured that if that many people (they had 30 or so registered attendees and 10 presentations) were going to spend that much time going over software that I had written, I should at least offer to show up!</p>
<p>I'd like to apologize for any errors in the romanization of people's names or misunderstandings I may have in the following text. My grasp of Japanese is very poor! Please feel free to send me corrections or additions!</p>
<h2>Surprise!</h2>
<p>Sadly, my <a href="https://twitter.com/mcscottmc">boss</a>'s immediate reaction to hearing that there was a workshop in Japan about my work was to quip that "You're saying you're <a href="http://en.wikipedia.org/wiki/Big_in_Japan_(phrase)">huge in Japan</a>?" With him conspicuously not offering to fly me out here, I had to settle for surprising the organizers and attending via Google Hangout.</p>
<h2>Commentary and Logs</h2>
<p><a href="http://twitter.com/nushio">@nushio</a> was very helpful in getting me connected, and while the speakers gave their talks I sat on the irc.freenode.net #haskell-lens channel and Google Hangout and answered questions and provided a running commentary with more details and references. Per <a href="http://freenode.net/channel_guidelines.shtml">freenode policy</a> the fact that we were logging the channel was announced -- well, at least before things got too far underway.</p>
<p><a href="https://gist.github.com/ekmett/5283253">Here is the IRC session log as a gist</a>. IKEGAMI Daisuke <a href="https://twitter.com/ikegami__">@ikegami__</a> (<code>ikeg</code> in the IRC log) tried to keep up a high-level running commentary about what was happening in the video to the log, which may be helpful if you are trying to follow along through each retroactively.</p>
<p>Other background chatter and material is strewn across twitter under the <a href="https://twitter.com/search?q=%23ekmett_conf&src=typd">#ekmett_conf</a> hash tag and on a japanese twitter aggregator named <a href="http://togetter.com/li/480399">togetter</a></p>
<p><span id="more-831"></span></p>
<h2>Getting Started</h2>
<p>The 1PM start time in Shibuya, Tokyo, Japan translates to midnight at the start of Easter here in Boston, which meant ~6 hours later when we reached the Q&A session, I was a bit loopy from lack of sleep, but they were incredibly polite and didn't seem to mind my long rambling responses.</p>
<p>Thanks to the organizers, we have video of the vast majority of the event! There was no audio for the first couple of minutes, and the recording machine lost power for the last talk and the Q&A session at the end as we ran somewhat longer than they had originally scheduled! -- And since I was attending remotely and a number of others flitted in and out over the course of the night, they were nice enough to put most of the slides and background material online.</p>
<h2>profunctors by Liyang HU and HIBINO Kei</h2>
<p><a href="http://liyang.hu/">Liyang Hu</a> (<a href="http://twitter.com/liyanghu">@liyanghu</a>) started the session off with a nicely self-contained crash course on my <a href="http://github.com/ekmett/profunctors">profunctors</a> package, since profunctors are used fairly heavily inside the implementation of <a href="http://github.com/ekmett/lens">lens</a> and <a href="http://github.com/ekmett/machines">machines</a>, with a couple of detours into <a href="http://github.com/ekmett/contravariant">contravariant</a> and <a href="http://github.com/ekmett/bifunctors">bifunctors</a>.</p>
<p><a href="https://www.fpcomplete.com/user/liyang/profunctors">His presentation materials</a> are available interactively from the new <a href="https://www.fpcomplete.com/">FP Complete</a> School of Haskell. You can also watch the <a href="http://www.ustream.tv/recorded/30668431/highlight/337429">video recording of his talk</a> on <a href="http://www.ustream.tv/">ustream</a>.</p>
<p>This talk was followed by a much more condensed version of very similar content <a href="http://www.ustream.tv/recorded/30668431/highlight/337431">in Japanese by Hibino Kei</a> (<a href="https://github.com/khibino">@khibino</a>) His talk was more focused on the relationship between arrows and profunctors, and the <a href="http://www.slideshare.net/khibino/profunctor-and-arrow-17939130"> slides are available through slideshare</a>.</p>
<h2>lens by @its_out_of_tune</h2>
<p>Once the necessary background material was out of the way, the talk on <a href="http://hackage.haskell.org/package/lens">lens</a> -- arguably the presentation that most of the people were there for -- came early. </p>
<p><a href="http://comonad.com/reader/wp-content/uploads/2013/03/ekmett_conf-its_out_of_tune-1.jpg"><img src="http://comonad.com/reader/wp-content/uploads/2013/03/ekmett_conf-its_out_of_tune-1.jpg" alt="ekmett_conf-its_out_of_tune-1" title="ekmett_conf-its_out_of_tune-1" width="1076" height="736" class="aligncenter size-full wp-image-835" /></a></p>
<p><a href="https://twitter.com/its_out_of_tune">@its_out_of_tune</a> gave an incredibly dense overview of how to use the main parts of the lens package in Japanese. <a href="http://www.slideshare.net/itsoutoftunethismymusic/ekmett-17955009">His slides are available online</a> and <a href="http://www.ustream.tv/recorded/30668431/highlight/337435">here is a recording of his talk</a>. </p>
<p>Over the course of a half hour, he was able to cram in a great cross-section of the library including material that I hadn't even been able to get to even with 4x the amount of time available during <a href="https://www.youtube.com/watch?v=cefnmjtAolY&hd=1">my New York talk</a> on how to use the lens template-haskell code to automatically generate lenses for user data types and how to use the lens <a href=http://hackage.haskell.org/packages/archive/lens/3.9.0.2/doc/html/Control-Lens-Action.html">Action</a> machinery.</p>
<h2>free and free-game by KINOSHITA Fumiaki</h2>
<p>Next up, was my <a href="http://hackage.haskell.org/package/free">free</a> package and the neat <a href="http://hackage.haskell.org/package/free-game">free-game</a> engine that Kinoshita Fumiaki (<a href="https://twitter.com/fumieval">@fumieval</a>) built on top.</p>
<p>The slides were in English, though the talk and humor were very Japanese. ^_^</p>
<p><a href="http://comonad.com/reader/wp-content/uploads/2013/03/ekmett_conf-free.jpg"><img src="http://comonad.com/reader/wp-content/uploads/2013/03/ekmett_conf-free.jpg" alt="ekmett_conf-free" title="ekmett_conf-free" width="1076" height="734" class="aligncenter size-full wp-image-852" /></a></p>
<p>That said, he had some amazingly nice demos, including a live demo of his tetris clone, <a href="https://github.com/fumieval/Monaris">Monaris</a>, which is visible about 10 minutes into <a href="http://www.ustream.tv/recorded/30668431/highlight/337437">the video</a>!</p>
<h2>ad by @nebutalab</h2>
<p><a href="http://twitter.com/nebutalab">@nebutalab</a>, like me, joined the session remotely through Google Hangout, and proceeded to give a tutorial on how <a href="http://en.wikipedia.org/wiki/Automatic_differentiation#Forward_accumulation">forward mode</a> automatic differentiation works through my <a href="http://github.com/ekmett/ad">AD</a> package.</p>
<p><a href="http://www.slideshare.net/nebuta/haskell-ad34">His slides were made available before the talk</a> and the video is available in <a href="http://www.ustream.tv/recorded/30671273/highlight/337441">two</a> <a href="http://www.ustream.tv/recorded/30671623/highlight/337439">parts</a> due a technical hiccup in the middle of the recording.</p>
<p><a href="http://comonad.com/reader/wp-content/uploads/2013/04/ekmett_conf-ad.jpg"><img src="http://comonad.com/reader/wp-content/uploads/2013/04/ekmett_conf-ad-300x204.jpg" alt="ekmett_conf-ad" title="ekmett_conf-ad" width="300" height="204" class="aligncenter size-medium wp-image-862" /></a></p>
<p>I'm currently working to drastically simplify the API for ad with <a href="https://github.com/alang9">Alex Lang</a>. Fortunately almost all of the material in this presentation will still be relevant to the new design.</p>
<h2>tables by MURAYAMA Shohei</h2>
<p>Next up, Murayama Shohei (<a href="https://twitter.com/yuga">@yuga</a>) gave an introduction to <a href="http://hackage.haskell.org/package/tables">tables</a>, which is a small in memory data-store that I wrote a few months back to sit on top of lens.</p>
<p><a href="http://www.ustream.tv/recorded/30672629/highlight/337395">Video of @yuga's talk</a> and <a href="https://gist.github.com/yuga/5279313">his slides</a> are available, which I think makes this the first public talk about this project. -_^</p>
<h2>machines by YOSHIDA Sanshiro</h2>
<p>Yoshida Sanshiro (<a href="http://twitter.com/halcat0x15a">@halcat0x15a</a>) gave a nice overview of the currently released version of <a href="http://hackage.haskell.org/package/machines">machines</a> including a lot of examples! I think he may have actually written more code using machines just for demonstrations than I have written using it myself.</p>
<p><a href="http://www.ustream.tv/recorded/30672629/highlight/337397">Video of his talk is available</a> along with <a href="http://halcat0x15a.github.com/slide/machines/out/#0">his slide deck</a> -- just tap left or right to move through the slides. He has also written <a href="http://krdlab.hatenablog.com/entry/2013/03/16/204039">a blog post</a> documenting his early explorations of the library, and some thoughts about using it with attoparsec.</p>
<p>I've recently been trying to redesign machines with coworker Paul CHIUSANO <a href="https://twitter.com/pchiusano">@pchiusano</a> and we've begun greatly simplifying the design of machines based on some work <a href="http://www.youtube.com/watch?v=8fC2V9HX_m8">he has been doing in Scala</a>, so unfortunately many of the particulars of this talk will be soon outdated, but the overall 'feel' of working with machines should be preserved across the change-over. Some of these changes can be seen in the <a href="http://github.com/ekmett/machines">master branch on github</a> now.</p>
<h2>More to come</h2>
<p>There were 4 more sessions, but alas, I'm out of time for the moment! I'll continue this write-up with more links to the source material and my thoughts as soon as I can tomorrow!</p>
]]></content:encoded>
			<wfw:commentRss>http://comonad.com/reader/2013/japanese-workshop-1/feed/</wfw:commentRss>
		<slash:comments>95</slash:comments>
		</item>
		<item>
		<title>Mirrored Lenses</title>
		<link>http://comonad.com/reader/2012/mirrored-lenses/</link>
		<comments>http://comonad.com/reader/2012/mirrored-lenses/#comments</comments>
		<pubDate>Mon, 25 Jun 2012 03:38:41 +0000</pubDate>
		<dc:creator>Edward Kmett</dc:creator>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Data Structures]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Lenses]]></category>
		<category><![CDATA[accessors]]></category>
		<category><![CDATA[functional references]]></category>
		<category><![CDATA[lens families]]></category>
		<category><![CDATA[van Laarhoven]]></category>

		<guid isPermaLink="false">http://comonad.com/reader/?p=600</guid>
		<description><![CDATA[Lenses are a great way to deal with functional references, but there are two common issues that arise from their use. 

There is a long-standing folklore position that lenses do not support polymorphic updates. This has actually caused a fair bit of embarrassment for the folks who'd like to incorporate lenses in any Haskell record [...]]]></description>
			<content:encoded><![CDATA[<p>Lenses are a great way to deal with functional references, but there are two common issues that arise from their use. </p>
<ol>
<li>There is a long-standing folklore position that lenses do not support polymorphic updates. This has actually caused a fair bit of embarrassment for the folks who'd like to incorporate lenses in any Haskell record system improvement.</li>
<li>Access control. It'd be nice to have read-only or write-only properties -- "one-way" or "mirrored" lenses, as it were. Moreover, lenses are commonly viewed as an all or nothing proposition, in that it is hard to mix them with arbitrary user functions.</li>
<li>Finally there is a bit of a cult around trying to generalize lenses by smashing a monad in the middle of them somewhere, it would be nice to be able to get into a list and work with each individual element in it without worrying about someone mucking up our lens laws, and perhaps avoid the whole generalized lens issue entirely.</li>
</ol>
<p>We'll take a whack at each of these concerns in turn today.<br />
<span id="more-600"></span></p>
<pre lang='haskell'>
   {-# LANGUAGE Rank2Types #-}  -- we'll relax this later
   import Data.Complex -- for complex examples
</pre>
<p>First, let us consider the type of van Laarhoven lenses:</p>
<pre lang='haskell'>
type Lens a b =
  forall f. Functor f =>
  (b -> f b) -> a -> f a
</pre>
<p>with a couple of examples:</p>
<pre class="haskell">&nbsp;
realLens :: <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:RealFloat"><span style="background-color: #efefbf; font-weight: bold;">RealFloat</span></a> a =&gt; Lens <span style="color: green;">&#40;</span>Complex a<span style="color: green;">&#41;</span> a
realLens f <span style="color: green;">&#40;</span>r :+ i<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span>:+ i<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>f r<span style="color: green;">&#41;</span>
&nbsp;
imagLens :: <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:RealFloat"><span style="background-color: #efefbf; font-weight: bold;">RealFloat</span></a> a =&gt; Lens <span style="color: green;">&#40;</span>Complex a<span style="color: green;">&#41;</span> a
imagLens f <span style="color: green;">&#40;</span>r :+ i<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span>r :+<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>f i<span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>These lenses have some very nice properties that we're going to exploit. By far their nicest property is that you can compose them using just <code>(.)</code> and <code>id</code> from the <code>Prelude</code> rather than having to go off and write a <code>Category</code>.</p>
<h2>Lens Families</h2>
<p><a href="http://r6.ca/blog/20120623T104901Z.html">Russell O'Connor recently noted that these lenses permit polymorphic update</a> if you simply generalize their type signature to</p>
<pre class="haskell">&nbsp;
<span style="color: #06c; font-weight: bold;">type</span> LensFamily a b c d =
  <span style="color: #06c; font-weight: bold;">forall</span> f. <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> f =&gt;
  <span style="color: green;">&#40;</span>c -&gt; f d<span style="color: green;">&#41;</span> -&gt; a -&gt; f b
&nbsp;</pre>
<p>I'd like to note that you can't just let these 4 arguments vary with complete impunity, so I'll be referring to these as "lens families" rather than polymorphic lenses, a point that I'll address further below. In short, we want the original lens laws to still hold in spite of the generalized type signature, and this forces some of these types to be related. </p>
<p>As an aside, each of the other lens types admit this same generalization! For instance the <code>Lens</code> type in <a href="http://hackage.haskell.org/package/data-lens">data-lens</a> can be generalized using an indexed store comonad:</p>
<pre class="haskell">&nbsp;
<span style="color: #06c; font-weight: bold;">data</span> Store c d b = Store <span style="color: green;">&#40;</span>d -&gt; b<span style="color: green;">&#41;</span> c
&nbsp;
<span style="color: #06c; font-weight: bold;">instance</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> <span style="color: green;">&#40;</span>Store c d<span style="color: green;">&#41;</span> <span style="color: #06c; font-weight: bold;">where</span>
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> f <span style="color: green;">&#40;</span>Store g c<span style="color: green;">&#41;</span> = Store <span style="color: green;">&#40;</span>f . g<span style="color: green;">&#41;</span> c
&nbsp;
<span style="color: #06c; font-weight: bold;">newtype</span> DataLensFamily a b c d = DataLensFamily <span style="color: green;">&#40;</span>a -&gt; Store c d b<span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>and we can freely convert back and forth to van Laarhoven lens families:</p>
<pre class="haskell">&nbsp;
dlens :: LensFamily a b c d -&gt; DataLensFamily a b c d
dlens l = DataLensFamily <span style="color: green;">&#40;</span>l <span style="color: green;">&#40;</span>Store <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
&nbsp;
plens :: DataLensFamily a b c d -&gt; LensFamily a b c d
plens <span style="color: green;">&#40;</span>DataLensFamily l<span style="color: green;">&#41;</span> f a = <span style="color: #06c; font-weight: bold;">case</span> l a <span style="color: #06c; font-weight: bold;">of</span>
  Store g c -&gt; <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> g <span style="color: green;">&#40;</span>f c<span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>I leave it as an exercise to the reader to generalize the other lens types, but we'll stick to van Laarhoven lens families almost exclusively below.</p>
<p>As Russell noted, we can define functions to get, modify and set the target of a lens very easily. I'll create local names for <code>Identity</code> and <code>Const</code>, mostly to help give nicer error messages later.</p>
<p>We can read from a lens family:</p>
<pre class="haskell">&nbsp;
<span style="color: #06c; font-weight: bold;">infixl</span> <span style="color: red;">8</span> ^.
<span style="color: #06c; font-weight: bold;">newtype</span> Getting b a = Getting <span style="color: green;">&#123;</span> got :: b <span style="color: green;">&#125;</span>
<span style="color: #06c; font-weight: bold;">instance</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> <span style="color: green;">&#40;</span>Getting b<span style="color: green;">&#41;</span> <span style="color: #06c; font-weight: bold;">where</span>
    <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> _ <span style="color: green;">&#40;</span>Getting b<span style="color: green;">&#41;</span> = Getting b
<span style="color: green;">&#40;</span>^.<span style="color: green;">&#41;</span> :: a -&gt; <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>c -&gt; Getting c d<span style="color: green;">&#41;</span> -&gt; a -&gt; Getting c b<span style="color: green;">&#41;</span> -&gt; c
x ^. l = got <span style="color: green;">&#40;</span>l Getting x<span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>We can modify the target of the lens:</p>
<pre class="haskell">&nbsp;
<span style="color: #06c; font-weight: bold;">newtype</span> Setting a = Setting <span style="color: green;">&#123;</span> unsetting :: a <span style="color: green;">&#125;</span>
<span style="color: #06c; font-weight: bold;">instance</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> Setting <span style="color: #06c; font-weight: bold;">where</span>
    <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> f <span style="color: green;">&#40;</span>Setting a<span style="color: green;">&#41;</span> = Setting <span style="color: green;">&#40;</span>f a<span style="color: green;">&#41;</span>
<span style="color: #06c; font-weight: bold;">infixr</span> <span style="color: red;">4</span> %=
<span style="color: green;">&#40;</span>%=<span style="color: green;">&#41;</span> :: <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>c -&gt; Setting d<span style="color: green;">&#41;</span> -&gt; a -&gt; Setting b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>c -&gt; d<span style="color: green;">&#41;</span> -&gt; a -&gt; b
l %= f = unsetting . l <span style="color: green;">&#40;</span>Setting . f<span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>We can set the target of the lens with impunity:</p>
<pre class="haskell">&nbsp;
<span style="color: #06c; font-weight: bold;">infixr</span> <span style="color: red;">4</span> ^=
<span style="color: green;">&#40;</span>^=<span style="color: green;">&#41;</span> :: <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>c -&gt; Setting d<span style="color: green;">&#41;</span> -&gt; a -&gt; Setting b<span style="color: green;">&#41;</span> -&gt; d -&gt; a -&gt; b
l ^= v = l %= <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:const"><span style="font-weight: bold;">const</span></a> v
&nbsp;</pre>
<p>We can build a lens family from a getter/setter pair</p>
<pre class="haskell">&nbsp;
lens :: <span style="color: green;">&#40;</span>a -&gt; c<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>a -&gt; d -&gt; b<span style="color: green;">&#41;</span> -&gt; LensFamily a b c d
lens f g h a = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span>g a<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>h <span style="color: green;">&#40;</span>f a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>or from a family of isomorphisms:</p>
<pre class="haskell">&nbsp;
iso :: <span style="color: green;">&#40;</span>a -&gt; c<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>d -&gt; b<span style="color: green;">&#41;</span> -&gt; LensFamily a b c d
iso f g h a = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> g <span style="color: green;">&#40;</span>h <span style="color: green;">&#40;</span>f a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>With these combinators in hand, we need some actual lens families to play with. Fortunately they are just as easy to construct as simple lenses. The only thing that changes is the type signature.  </p>
<pre class="haskell">&nbsp;
fstLens :: LensFamily <span style="color: green;">&#40;</span>a,c<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>b,c<span style="color: green;">&#41;</span> a b
fstLens f <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span>\x -&gt; <span style="color: green;">&#40;</span>x,b<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>f a<span style="color: green;">&#41;</span>
&nbsp;
sndLens :: LensFamily <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>a,c<span style="color: green;">&#41;</span> b c
sndLens f <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> = <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>,<span style="color: green;">&#41;</span> a<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>f b<span style="color: green;">&#41;</span>
&nbsp;
swap :: <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>b,a<span style="color: green;">&#41;</span>
swap <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> = <span style="color: green;">&#40;</span>b,a<span style="color: green;">&#41;</span>
&nbsp;
swapped :: LensFamily <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>c,d<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>b,a<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>d,c<span style="color: green;">&#41;</span>
swapped = iso swap swap
&nbsp;</pre>
<p>These can also build 'traditional' lenses:</p>
<pre class="haskell">&nbsp;
negated :: <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Num"><span style="background-color: #efefbf; font-weight: bold;">Num</span></a> a =&gt; Lens a a
negated = iso <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:negate"><span style="font-weight: bold;">negate</span></a> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:negate"><span style="font-weight: bold;">negate</span></a>
&nbsp;</pre>
<p>And since <code>Lens</code> and <code>LensFamily</code> are both type aliases, we can freely mix and match lenses with lens families:</p>
<pre class="haskell">&nbsp;
ghci&gt; <span style="color: green;">&#40;</span><span style="color: red;">1</span>:<span style="color: red;">+2</span>,<span style="color: red;">3</span><span style="color: green;">&#41;</span> ^.fstLens.realLens
<span style="color: red;">1.0</span>
ghci&gt; fstLens . realLens ^= <span style="color: red;">4</span> $ <span style="color: green;">&#40;</span><span style="color: red;">1</span>:<span style="color: red;">+2</span>,<span style="color: red;">3</span><span style="color: green;">&#41;</span>
<span style="color: green;">&#40;</span><span style="color: red;">4.0</span> :+ <span style="color: red;">2.0</span>,<span style="color: red;">3</span><span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>But, we can now change types with our lens updates!</p>
<pre class="haskell">&nbsp;
ghci&gt; <span style="color: green;">&#40;</span>fstLens . sndLens ^= <span style="color: #3c7331;">&quot;hello&quot;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span><span style="color: red;">1</span>,<span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>,<span style="color: red;">3</span><span style="color: green;">&#41;</span>
<span style="color: green;">&#40;</span><span style="color: green;">&#40;</span><span style="color: red;">1</span>,<span style="color: #3c7331;">&quot;hello&quot;</span><span style="color: green;">&#41;</span>,<span style="color: red;">3</span><span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>We can even do things like use the combinator</p>
<pre class="haskell">&nbsp;
traverseLens :: <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>c -&gt; c<span style="color: green;">&#41;</span> -&gt; a -&gt; b<span style="color: green;">&#41;</span> -&gt; a -&gt; b
traverseLens f = f <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a>
&nbsp;</pre>
<p>to project a <code>Functor</code> out through an appropriate lens family:</p>
<pre class="haskell">&nbsp;
ghci&gt; :t traverseLens <span style="color: green;">&#40;</span>fstLens . sndLens<span style="color: green;">&#41;</span>
traverseLens <span style="color: green;">&#40;</span>fstLens . sndLens<span style="color: green;">&#41;</span>
  :: <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> f =&gt; <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a, f b<span style="color: green;">&#41;</span>, c<span style="color: green;">&#41;</span> -&gt; f <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>a, b<span style="color: green;">&#41;</span>, c<span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>That takes care of polymorphic updates. </p>
<h2>Why is it a Lens Family?</h2>
<p>So, why do I use the term "lens family" rather than "polymorphic lens"?</p>
<p>In order for the lens laws to hold, the 4 types parameterizing our lens family must be interrelated.</p>
<p>In particular you need to be able to put back (with <code>^=</code>) what you get out of the lens (with <code>^.</code>) and put multiple times.</p>
<p>This effectively constrains the space of possible legal lens families to those where there exists an index kind <code>i</code>, and two type families <code>outer :: i -> *</code>, and <code>inner :: i -> *</code>. If this were a viable type signature, then each lens family would actually have 2 parameters, yielding something like:</p>
<pre class="haskell">&nbsp;
<span style="color: #5d478b; font-style: italic;">-- pseudo-Haskell</span>
<span style="color: #5d478b; font-style: italic;">-- type LensFamily outer inner =</span>
<span style="color: #5d478b; font-style: italic;">--    forall a b. LensFamily (outer a) (outer b) (inner a) (inner b)</span>
&nbsp;</pre>
<p>but you can't pass in type families as arguments like that, and even if you could, their lack of injectivity doesn't give the type checker enough to work with to compose your lenses. By specifying all 4 type arguments independently, we give the compiler enough to work with. But since the arguments aren't just freely polymorphic and are instead related by these index types, I'm choosing to call them "lens families" rather than "polymorphic lenses".</p>
<h2>Getters</h2>
<p>Note, we didn't use the full polymorphism of the van Laarhoven lenses in the signatures of <code>(^.)</code>, <code>(%=)</code> and <code>(^=)</code> above.</p>
<p>What happens when we restrict the type of <code>Functor</code> we're allowed to pass to our lens?</p>
<p>If we generalize the type of our getter ever so slightly from the type we pass to <code>(^.)</code> to permit composition, we get:</p>
<pre class="haskell">&nbsp;
<span style="color: #06c; font-weight: bold;">type</span> Getter a c = <span style="color: #06c; font-weight: bold;">forall</span> r d b. <span style="color: green;">&#40;</span>c -&gt; Getting r d<span style="color: green;">&#41;</span> -&gt; a -&gt; Getting r b
&nbsp;</pre>
<p>and we can make getters out of arbitrary Haskell functions that we have lying around with</p>
<pre class="haskell">&nbsp;
<span style="color: #5d478b; font-style: italic;">-- | build a getting out of a function</span>
getting :: <span style="color: green;">&#40;</span>a -&gt; b<span style="color: green;">&#41;</span> -&gt; Getter a b
getting g f = Getting . got . f . g
&nbsp;</pre>
<p>For example:</p>
<pre class="haskell">&nbsp;
getFst :: Getter <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> a
getFst = getting <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fst"><span style="font-weight: bold;">fst</span></a>
&nbsp;
getSnd :: Getter <span style="color: green;">&#40;</span>a,b<span style="color: green;">&#41;</span> b
getSnd = getting <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:snd"><span style="font-weight: bold;">snd</span></a>
&nbsp;</pre>
<p>But this is particularly nice for things that <em>can't</em> be made into real lenses or lens families, because of loss of information:</p>
<pre class="haskell">&nbsp;
getPhase :: <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:RealFloat"><span style="background-color: #efefbf; font-weight: bold;">RealFloat</span></a> a =&gt; Getter <span style="color: green;">&#40;</span>Complex a<span style="color: green;">&#41;</span> a
getPhase = getting phase
&nbsp;
getAbs, getSignum  :: <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Num"><span style="background-color: #efefbf; font-weight: bold;">Num</span></a> a =&gt; Getter a a
getAbs = getting <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:abs"><span style="font-weight: bold;">abs</span></a>
getSignum = getting <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:signum"><span style="font-weight: bold;">signum</span></a>
&nbsp;</pre>
<p>Notably, <code>getMagnitude</code> and <code>getPhase</code> can't be legal lenses because when the <code>magnitude</code> is 0, you lose <code>phase</code> information.</p>
<p>These can be mixed and matched with other lenses when dereferencing with <code>(^.)</code></p>
<pre class="haskell">&nbsp;
ghci&gt; <span style="color: green;">&#40;</span><span style="color: red;">0</span>,<span style="color: green;">&#40;</span><span style="color: red;">1</span>:<span style="color: red;">+2</span>,<span style="color: red;">3</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> ^. getting <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:snd"><span style="font-weight: bold;">snd</span></a> . fstLens . getting magnitude
<span style="color: red;">2.23606797749979</span>
&nbsp;</pre>
<p>But we get a type error when we attempt to write to a <code>Getter</code>.</p>
<pre class="haskell">&nbsp;
ghci&gt; getting magnitude ^= <span style="color: red;">12</span>
&lt;interactive&gt;:<span style="color: red;">2</span>:<span style="color: red;">1</span>:
    Couldn't match expected <span style="color: #06c; font-weight: bold;">type</span> `Setting d0'
                with actual <span style="color: #06c; font-weight: bold;">type</span> `Getting r0 d1'
    Expected <span style="color: #06c; font-weight: bold;">type</span>: <span style="color: green;">&#40;</span>c0 -&gt; Setting d0<span style="color: green;">&#41;</span> -&gt; a1 -&gt; Setting b1
      Actual <span style="color: #06c; font-weight: bold;">type</span>: <span style="color: green;">&#40;</span>c0 -&gt; Getting r0 d1<span style="color: green;">&#41;</span> -&gt; a0 -&gt; Getting r0 b0
    In the <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return"><span style="font-weight: bold;">return</span></a> <span style="color: #06c; font-weight: bold;">type</span> <span style="color: #06c; font-weight: bold;">of</span> a call <span style="color: #06c; font-weight: bold;">of</span> `getting'
    In the first argument <span style="color: #06c; font-weight: bold;">of</span> `<span style="color: green;">&#40;</span>^=<span style="color: green;">&#41;</span>', namely `getting magnitude'
&lt;/interactive&gt;</pre>
<h2>Setters</h2>
<p>So what about write-only properties?</p>
<p>These have a less satisfying solution. We have to break our lens family structure slightly to make something that can strictly <em>only</em> be written to, by disabling the ability to read our current value entirely. </p>
<pre class="haskell">&nbsp;
<span style="color: #06c; font-weight: bold;">type</span> Setter a d b = <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> -&gt; Setting d<span style="color: green;">&#41;</span> -&gt; a -&gt; Setting b
&nbsp;
setting :: <span style="color: green;">&#40;</span>a -&gt; d -&gt; b<span style="color: green;">&#41;</span> -&gt; Setter a d b
setting f g a = Setting <span style="color: green;">&#40;</span>f a <span style="color: green;">&#40;</span>unsetting <span style="color: green;">&#40;</span>g <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>Now we can make setters out of functions that take two arguments:</p>
<pre class="haskell">&nbsp;
plus, times :: <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Num"><span style="background-color: #efefbf; font-weight: bold;">Num</span></a> a =&gt; Setter a a a
plus = setting <span style="color: green;">&#40;</span>+<span style="color: green;">&#41;</span>
times = setting <span style="color: green;">&#40;</span>*<span style="color: green;">&#41;</span>
&nbsp;</pre>
<pre class="haskell">&nbsp;
ghci&gt; setting <span style="color: green;">&#40;</span>+<span style="color: green;">&#41;</span> ^= <span style="color: red;">12</span> $ <span style="color: red;">32</span>
<span style="color: red;">44</span>
ghci&gt; fstLens . setting <span style="color: green;">&#40;</span>*<span style="color: green;">&#41;</span> ^= <span style="color: red;">12</span> $ <span style="color: green;">&#40;</span><span style="color: red;">2</span>,<span style="color: red;">3</span><span style="color: green;">&#41;</span>
<span style="color: green;">&#40;</span><span style="color: red;">24</span>,<span style="color: red;">3</span><span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>However, these lenses have the unsatisfying property that they can only be placed last in the chain of lenses we're setting. </p>
<pre class="haskell">&nbsp;
ghci&gt; <span style="color: green;">&#40;</span>setting <span style="color: green;">&#40;</span>+<span style="color: green;">&#41;</span> . realLens ^= <span style="color: red;">12</span><span style="color: green;">&#41;</span> <span style="color: red;">1</span>
&lt;interactive&gt;:<span style="color: red;">15</span>:<span style="color: red;">16</span>:
    Couldn't match expected <span style="color: #06c; font-weight: bold;">type</span> `<span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>' with actual <span style="color: #06c; font-weight: bold;">type</span> `Complex d0'
    Expected <span style="color: #06c; font-weight: bold;">type</span>: <span style="color: green;">&#40;</span>d0 -&gt; Setting d0<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> -&gt; Setting b0
      Actual <span style="color: #06c; font-weight: bold;">type</span>: <span style="color: green;">&#40;</span>d0 -&gt; Setting d0<span style="color: green;">&#41;</span>
                   -&gt; Complex d0 -&gt; Setting <span style="color: green;">&#40;</span>Complex d0<span style="color: green;">&#41;</span>
    In the second argument <span style="color: #06c; font-weight: bold;">of</span> `<span style="color: green;">&#40;</span>.<span style="color: green;">&#41;</span>', namely `realLens'
    In the first argument <span style="color: #06c; font-weight: bold;">of</span> `<span style="color: green;">&#40;</span>^=<span style="color: green;">&#41;</span>', namely `setting <span style="color: green;">&#40;</span>+<span style="color: green;">&#41;</span> . realLens'
&lt;/interactive&gt;</pre>
<p>This isn't surprising, if you consider that to compose <code>data-lens</code> lenses you need to use <code>%=</code> to chain setters.</p>
<h2>Modifiers</h2>
<p>So what do we need to do to make a lens we can only modify but not read?</p>
<p>Lets restore the lens family structure!</p>
<pre class="haskell">&nbsp;
<span style="color: #06c; font-weight: bold;">type</span> Modifier a b c d = <span style="color: green;">&#40;</span>c -&gt; Setting d<span style="color: green;">&#41;</span> -&gt; a -&gt; Setting b
&nbsp;
modifying :: <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>c -&gt; d<span style="color: green;">&#41;</span> -&gt; a -&gt; b<span style="color: green;">&#41;</span> -&gt; Modifier a b c d
modifying f g a = Setting <span style="color: green;">&#40;</span>f <span style="color: green;">&#40;</span>unsetting . g<span style="color: green;">&#41;</span> a<span style="color: green;">&#41;</span>
&nbsp;</pre>
<p><code>modifying</code> makes a modify-only lens family you can modify using local information, but can't tell anyone about the contents of.</p>
<p>This lets us work with a lens over a variable number of elements in a structure, without worrying about a user accidentally "putting back" too many or too few entries.</p>
<pre class="haskell">&nbsp;
ghci&gt; modifying <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:map"><span style="font-weight: bold;">map</span></a> %= <span style="color: green;">&#40;</span><span style="color: red;">+1</span><span style="color: green;">&#41;</span> $ <span style="color: green;">&#91;</span><span style="color: red;">1</span>,<span style="color: red;">2</span>,<span style="color: red;">3</span><span style="color: green;">&#93;</span>
<span style="color: green;">&#91;</span><span style="color: red;">2</span>,<span style="color: red;">3</span>,<span style="color: red;">4</span><span style="color: green;">&#93;</span>
&nbsp;</pre>
<p>They can be composed with other lenses:</p>
<pre class="haskell">&nbsp;
ghci&gt; modifying <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:map"><span style="font-weight: bold;">map</span></a> . sndLens %= <span style="color: green;">&#40;</span><span style="color: red;">+1</span><span style="color: green;">&#41;</span> $ <span style="color: green;">&#91;</span><span style="color: green;">&#40;</span><span style="color: #3c7331;">&quot;hello&quot;</span>,<span style="color: red;">1</span><span style="color: green;">&#41;</span>,<span style="color: green;">&#40;</span><span style="color: #3c7331;">&quot;goodbye&quot;</span>,<span style="color: red;">2</span><span style="color: green;">&#41;</span><span style="color: green;">&#93;</span>
<span style="color: green;">&#91;</span><span style="color: green;">&#40;</span><span style="color: #3c7331;">&quot;hello&quot;</span>,<span style="color: red;">2</span><span style="color: green;">&#41;</span>,<span style="color: green;">&#40;</span><span style="color: #3c7331;">&quot;goodbye&quot;</span>,<span style="color: red;">3</span><span style="color: green;">&#41;</span><span style="color: green;">&#93;</span>
&nbsp;</pre>
<p>and unlike with a <code>Setter</code>, you can compose a <code>Modifier</code> with a <code>Modifier</code>:</p>
<pre class="haskell">&nbsp;
modifying <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> . modifying <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a>
  :: <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> g, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="background-color: #efefbf; font-weight: bold;">Functor</span></a> f<span style="color: green;">&#41;</span> =&gt;
     <span style="color: green;">&#40;</span>c -&gt; Setting d<span style="color: green;">&#41;</span> -&gt; f <span style="color: green;">&#40;</span>g c<span style="color: green;">&#41;</span> -&gt; Setting <span style="color: green;">&#40;</span>f <span style="color: green;">&#40;</span>g d<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>but they cannot be read from directly:</p>
<pre class="haskell">&nbsp;
ghci&gt; <span style="color: green;">&#91;</span><span style="color: red;">1</span>,<span style="color: red;">2</span>,<span style="color: red;">3</span><span style="color: green;">&#93;</span> ^. modifying <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a>
&lt;interactive&gt;:<span style="color: red;">18</span>:<span style="color: red;">12</span>:
    Couldn't match expected <span style="color: #06c; font-weight: bold;">type</span> `Getting c0 d0'
                with actual <span style="color: #06c; font-weight: bold;">type</span> `Setting d1'
    Expected <span style="color: #06c; font-weight: bold;">type</span>: <span style="color: green;">&#40;</span>c0 -&gt; Getting c0 d0<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#91;</span>t0<span style="color: green;">&#93;</span> -&gt; Getting c0 b1
      Actual <span style="color: #06c; font-weight: bold;">type</span>: Modifier a0 b0 c0 d1
    In the <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return"><span style="font-weight: bold;">return</span></a> <span style="color: #06c; font-weight: bold;">type</span> <span style="color: #06c; font-weight: bold;">of</span> a call <span style="color: #06c; font-weight: bold;">of</span> `modifying'
    In the second argument <span style="color: #06c; font-weight: bold;">of</span> `<span style="color: green;">&#40;</span>^.<span style="color: green;">&#41;</span>', namely `modifying <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:map"><span style="font-weight: bold;">map</span></a>'
&lt;/interactive&gt;</pre>
<p>We can map over restricted domains:</p>
<pre class="haskell">&nbsp;
reals :: <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:RealFloat"><span style="background-color: #efefbf; font-weight: bold;">RealFloat</span></a> a, <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:RealFloat"><span style="background-color: #efefbf; font-weight: bold;">RealFloat</span></a> b<span style="color: green;">&#41;</span> =&gt; Modifier <span style="color: green;">&#40;</span>Complex a<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>Complex b<span style="color: green;">&#41;</span> a b
reals = modifying <span style="color: green;">&#40;</span>\f <span style="color: green;">&#40;</span>r :+ i<span style="color: green;">&#41;</span> -&gt; f r :+ f i<span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>and everything still composes:</p>
<pre class="haskell">&nbsp;
ghci&gt; reals %= <span style="color: green;">&#40;</span><span style="color: red;">+1</span><span style="color: green;">&#41;</span> $  <span style="color: red;">1</span> :+ <span style="color: red;">2</span>
<span style="color: red;">2</span> :+ <span style="color: red;">3</span>
ghci&gt; fstLens . reals %= <span style="color: green;">&#40;</span><span style="color: red;">+1</span><span style="color: green;">&#41;</span> $ <span style="color: green;">&#40;</span><span style="color: red;">1</span> :+ <span style="color: red;">2</span>, <span style="color: red;">4</span><span style="color: green;">&#41;</span>
<span style="color: green;">&#40;</span><span style="color: red;">2.0</span> :+ <span style="color: red;">3.0</span>,<span style="color: red;">4</span><span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>These aren't limited to actions that map over the entire structure, however!</p>
<pre class="haskell">&nbsp;
ghci&gt; :m + Data.Lens
ghci&gt; modifying <span style="color: green;">&#40;</span>`adjust` <span style="color: #3c7331;">&quot;goodbye&quot;</span><span style="color: green;">&#41;</span> %= <span style="color: green;">&#40;</span><span style="color: red;">+1</span><span style="color: green;">&#41;</span> $
      fromList <span style="color: green;">&#91;</span><span style="color: green;">&#40;</span><span style="color: #3c7331;">&quot;hello&quot;</span>,<span style="color: red;">1</span><span style="color: green;">&#41;</span>,<span style="color: green;">&#40;</span><span style="color: #3c7331;">&quot;goodbye&quot;</span>,<span style="color: red;">2</span><span style="color: green;">&#41;</span><span style="color: green;">&#93;</span>
fromList <span style="color: green;">&#91;</span><span style="color: green;">&#40;</span><span style="color: #3c7331;">&quot;goodbye&quot;</span>,<span style="color: red;">3</span><span style="color: green;">&#41;</span>,<span style="color: green;">&#40;</span><span style="color: #3c7331;">&quot;hello&quot;</span>,<span style="color: red;">1</span><span style="color: green;">&#41;</span><span style="color: green;">&#93;</span>
&nbsp;</pre>
<p>This lets us update potentially nested structures where something may or may not be present , which was fairly tedious to do with earlier lens representations.</p>
<p>Both the former map-like example and the latter update-like behavior were commonly used examples in calls for partial lenses or 'multi-lenses', but here they are able to implemented using a restricted form of a more traditional lens type, and moreover they compose cleanly with other lenses and lens families.</p>
<h2>Rank-1 Lens Families</h2>
<p>At the very start I mentioned that you can dispense with the need for Rank-2 Types. Doing so requires much more tedious type signatures as the <code>LensFamily</code>, <code>Getter</code>, <code>Setter</code> and <code>Lens</code> aliases are no longer legal. Also, if you want to take a lens as an argument and use it in multiple contexts (e.g. as both a getter and a setter), you'll need to clone it to obtain a lens family. For example, this fails:</p>
<pre class="haskell">&nbsp;
ghci&gt; :t \l y -&gt; l ^= y ^. l + <span style="color: red;">1</span> $ y
&lt;interactive&gt;:<span style="color: red;">1</span>:<span style="color: red;">19</span>:
    Couldn't match expected <span style="color: #06c; font-weight: bold;">type</span> `Getting d0 d1'
                with actual <span style="color: #06c; font-weight: bold;">type</span> `Setting d0'
    Expected <span style="color: #06c; font-weight: bold;">type</span>: <span style="color: green;">&#40;</span>d0 -&gt; Getting d0 d1<span style="color: green;">&#41;</span> -&gt; a1 -&gt; Getting d0 b1
      Actual <span style="color: #06c; font-weight: bold;">type</span>: <span style="color: green;">&#40;</span>d0 -&gt; Setting d0<span style="color: green;">&#41;</span> -&gt; a0 -&gt; Setting b0
    In the second argument <span style="color: #06c; font-weight: bold;">of</span> `<span style="color: green;">&#40;</span>^.<span style="color: green;">&#41;</span>', namely `l'
    In the first argument <span style="color: #06c; font-weight: bold;">of</span> `<span style="color: green;">&#40;</span>+<span style="color: green;">&#41;</span>', namely `y ^. l'
&lt;/interactive&gt;</pre>
<p>But we can clone the supplied monomorphic lens using the composition of <code>dlens</code> and <code>plens</code> above, since the <code>DataLensFamily</code> completely characterizes the <code>LensFamily</code> with:</p>
<pre class="haskell">&nbsp;
clone ::
  <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>c -&gt; Store c d d<span style="color: green;">&#41;</span> -&gt; <span style="color: green;">&#40;</span>a -&gt; Store c d b<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> -&gt;
  LensFamily a b c d
clone l f a = <span style="color: #06c; font-weight: bold;">case</span> l <span style="color: green;">&#40;</span>Store <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a><span style="color: green;">&#41;</span> a <span style="color: #06c; font-weight: bold;">of</span>
  Store g c -&gt; <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> g <span style="color: green;">&#40;</span>f c<span style="color: green;">&#41;</span>
&nbsp;</pre>
<p>and then the following code type checks:</p>
<pre class="haskell">&nbsp;
ghci&gt; :t \l y -&gt; clone l ^= y ^. clone l + <span style="color: red;">1</span> $ y
\l y -&gt; clone l ^= y ^. clone l + <span style="color: red;">1</span> $ y
  :: <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Num"><span style="background-color: #efefbf; font-weight: bold;">Num</span></a> d =&gt; <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>c -&gt; Store c d1 d1<span style="color: green;">&#41;</span> -&gt; a -&gt; Store d d b<span style="color: green;">&#41;</span> -&gt; a -&gt; b
&nbsp;</pre>
<p>This means you could implement an entire library to deal with lens families with restricted getters and setters and remain within the confines of Haskell 98. However, the type signatures are considerably less elegant than what becomes available when you simply add Rank2Types.</p>
<h2>Conclusion</h2>
<p>So, we've demonstrated that van Laarhoven lens families let you have lenses that permit polymorphic update, let you offer lenses that are restricted to only allowing the use of getters, setters or modifiers, while granting you easy composition with the existing <code>(.)</code> and <code>id</code> from the <code>Prelude</code>.</p>
<p>I think the practical existence and power of these combinators make a strong case for their use in any serious record reform proposal.</p>
<p>My thanks go to Russell O'Connor. He first noticed that you can generalize van Laarhoven lenses and proposed the <code>clone</code> combinator as a path to Haskell 98/2010 compatibility, while retaining the nicer composition model.</p>
]]></content:encoded>
			<wfw:commentRss>http://comonad.com/reader/2012/mirrored-lenses/feed/</wfw:commentRss>
		<slash:comments>491</slash:comments>
		</item>
	</channel>
</rss>
