<br><br><div class="gmail_quote">On Fri, Aug 3, 2012 at 10:11 AM, Jonathan Geddes <span dir="ltr"><<a href="mailto:geddes.jonathan@gmail.com" target="_blank">geddes.jonathan@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The nice part about the SEC functions is that<div>they compose as regular functions. Lenses are</div><div>
super powerful in that they form a category.</div><div>Unfortunately using categories other than</div><div>functions feels a tad unwieldy because you</div><div>have to hide something from prelude and then</div><div>import Category. (A bit like exceptions,</div>
<div>currently).</div></blockquote><div><br>FWIW this is also true for van Laarhoven lenses[1]<br><br>type FTLens a b = forall f. Functor f => (b -> f b) -> (a -> f a)<br><br>newtype Const a b = Const { unConst :: a } deriving Functor<br>
<br>get :: FTLens a b -> a -> b<br>get ft = unConst . ft Const<br><br>{-<br>ft :: forall f. (b -> f b) -> (a -> f a)<br>Const :: forall x. b -> Const b x<br>ft Const :: a -> Const b a<br>-}<br><br>newtype Id a = Id { unId :: a } deriving Functor<br>
<br>set :: FTLens a b -> b -> a -> a<br>set ft b = unId . ft (\_ -> Id b)<br><br>modify :: FTLens a b -> (b -> b) -> a -> a<br>modify ft k = unId . ft (Id . k)<br><br>-- example<br>fstLens :: FTLens (a,b) a<br>
fstLens aToFa (a,b) = (,b) <$> aToFa a<br><br>-- and you get<br>compose :: FTLens b c -> FTLens a b -> FTLens a c<br>compose = (.)<br><br>identity :: FTLens a a<br>identity = id<br><br><br><br><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><br></div><div>If you like the look of "set" with lenses,</div><div>you could define a helper function to use</div><div>with SEC updaters.</div><div><br></div><div>>set :: ((b -> a) -> c) -> a -> c</div>
<div>>set sec = sec . const</div><div>></div><div>>--and then use it like so:</div><div>>setPersonsSalary :: Salary -> Person -> Person</div><div>>setPersonsSalary salary = set personsSalary' salary</div>
<div><br></div><div>With it you can use an updater as a setter.</div><div>I'd like to reiterate one of finer points of</div><div>the original proposal.</div><div class="im"><div><br></div><div>>The compiler could disallow using old-style</div>
<div>>update syntax for fields whose SEC update</div><div>>function is not in scope, giving us</div><div>>fine-grained control over access and update.</div><div>>On the other hand we currently have to create</div>
<div>>new functions to achieve this (exporting the</div><div>>getter means exporting the ability to update</div></div><div>>[using update syntax] as well, currently).</div><div><br></div><div>And now back to lenses:</div>
<div class="im">
<div><br></div><div>>it is really convenient how lenses let you compose the getter</div><div>>and setter together.</div><div><br></div></div><div>I don't recall too many cases where having the</div><div>getter and setter and modifier all in one</div>
<div>place was terribly useful. Could anyone give</div><div>me an example? But again, where that is</div><div>useful, a lens can be created from a getter</div><div>and a SEC updater.</div><div><br></div><div>Thoughts?</div>
<span class="HOEnZb"><font color="#888888">
<div><br></div><div>--Jonathan</div>
</font></span><br>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
<br></blockquote></div><br>