As soon as you have a distinct Lens type, and use something Category-like for 
composition, you are limiting yourself to composing two lenses to get back a 
lens (barring a terrible mptc 'solution'). And that is weak. The only reason I 
(personally) think lens pulls its weight, and is worth using (unlike every 
prior lens library, which I never bothered with), is the ability for lenses, 
prisms, ismorphisms, traversals, folds, etc. to properly degrade to one another 
and compose automatically.​
Aha.  I keep asking whether it’s just the cute ability to re-use (.) that 
justifies the lack of abstraction in the Lens type.  But Dan’s comment has made 
me remember something from my own talk on the subject.  Here are the types of 
lenses and traversals (2-parameter versions):


type Lens’      s a = forall f. Functor f

                           => (a -> f a) -> (s -> f s)

type Traversal’ s a = forall f. Applicative f

                           => (a -> f a) -> (s -> f s)

Suppose we have

ln1 :: Lens'      s1 s2

tr1 :: Traversal' s1 s2

ln2 :: Lens'      s2 a

tr2 :: Traversal' s2 a

Now these compositions are all well typed

ln1 . ln2 :: Lens' s1 a

tr1 . tr2 :: Traversal' s1 a

tr1 . ln2 :: Traversal' s1 a

ln1 . tr2 :: Traversal' s1 a

which is quite remarkable.  If Lens’ and Traversal’ were newtypes, you’d need 
four different operators.  (I think that what Dan means by “a terrible mptc 
solution” is trying to overload those four operators into one.)

I don’t know if this exhausts the reasons that lenses are not abstract.  I 
would love to know more, explained in a smilar style.

Incidentally has anyone explored this?


newtype PolyLens c s a = PL (forall f. c f => (a -> f a) -> s -> f s)


I’ve just abstracted over the Functor/Applicative part, so that Lens’ and 
Traversal’ are both PolyLenses.  Now perhaps we can do (.), with a type like


(.) :: PolyLens c1 s1 s2 -> PolyLens c2 s2 a -> PolyLens (And c1 c2) s1 a

where And is a type function


type instance And Functor Applicative = Applicative
etc

I have no idea whether this could be made to work out, but it seems like an 
obvious avenue so I wonder if anyone has explored it.

Simon

From: Dan Doel [mailto:dan.d...@gmail.com]
Sent: 28 January 2015 00:27
To: Edward Kmett
Cc: Simon Peyton Jones; ghc-devs@haskell.org
Subject: Re: GHC support for the new "record" package

On Tue, Jan 27, 2015 at 6:47 PM, Edward Kmett 
<ekm...@gmail.com<mailto:ekm...@gmail.com>> wrote:

This works great for lenses that don't let you change types.

​This is not the only restriction required for this to be an acceptable 
solution.
As soon as you have a distinct Lens type, and use something Category-like for 
composition, you are limiting yourself to composing two lenses to get back a 
lens (barring a terrible mptc 'solution'). And that is weak. The only reason I 
(personally) think lens pulls its weight, and is worth using (unlike every 
prior lens library, which I never bothered with), is the ability for lenses, 
prisms, ismorphisms, traversals, folds, etc. to properly degrade to one another 
and compose automatically. So if we're settling on a nominal Lens type in a 
proposal, then it is automatically only good for one thing to me: defining 
values of the better lens type.​
-- Dan
_______________________________________________
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs

Reply via email to