Writing or generating lenses for nonrecord datatypes

59 Views Asked by At

I have a nonrecord newtype which I would like to generate the lenses for:

newtype Foo = Foo (Int, String)

I would like to make a named lenses for it, currently I'm doing manually like follows:

bar :: Lans' Foo Int
bar = lens
  (\(Foo (x, y)) -> x)
  (\(Foo (x,y)) x' -> Foo (x', y))

I would prefer either using some TH magic here or at least more sophisticated syntax like:

bar :: Lens' Foo Int
bar = Foo <$> _1

Is it somehow possible?

1

There are 1 best solutions below

1
K. A. Buhr On BEST ANSWER

You're probably looking for Control.Lens.Wrapped to handle the newtype. You can construct a Wrapped instance via generics:

newtype Foo = Foo (Int, String) deriving (Generic)
instance Wrapped Foo

and can then write:

bar :: Lens' Foo Int
bar = _Wrapped' . _1