Almost every time I make a record, I find myself adding makeLenses ''Record
(from lens) immediately afterwards, and I never end up actually using the projection functions that the record gives me. In fact, looking at what makeLenses
produces (with the GHC -ddump-splices
flag), it looks like not even it uses those projection functions, except to choose a name for the lenses it produces.
Is there some way, either through TemplateHaskell
, or through a preprocessor, or frankly any other magic, that I could get record projection functions to be straight up Van Laarhoven lenses instead?
To be clear, that would mean that
data Record a b = Record { x :: a, y :: b }
Would generate (with type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
)
x :: forall a b c. Lens (Record a b) (Record c b) a c
x f (Record _x _y) = fmap (\x' -> Record x' _y) (f _x)
y :: forall a b c. Lens (Record a b) (Record a c) b c
y f (Record _x _y) = fmap (\ y' -> Record _x y') (f _y)
Instead of
x :: forall a b. Record a b -> a
x (Record _x _y) = _x
y :: forall a b. Record a b -> b
y (Record _x _y) = _y
It would not only get rid of the boilerplate makeLenses
but also free up the namespace (since the projection functions wouldn't ever be defined).
This is such a minor thing, but since it's attached to all my records, and records aren't such a rare thing, it is really starting to get on my nerves...