Search code examples
haskellhaskell-lens

Writing or generating lenses for nonrecord datatypes


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?


Solution

  • 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