Writing or generating lenses for nonrecord datatypes

maj*_*zak 2 haskell haskell-lens

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

newtype Foo = Foo (Int, String)
Run Code Online (Sandbox Code Playgroud)

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))
Run Code Online (Sandbox Code Playgroud)

我更喜欢在这里使用一些 TH 魔法,或者至少使用更复杂的语法,例如:

bar :: Lens' Foo Int
bar = Foo <$> _1
Run Code Online (Sandbox Code Playgroud)

这有可能吗?

K. *_*uhr 5

您可能正在寻找Control.Lens.Wrapped处理新类型的方法。Wrapped您可以通过泛型构造一个实例:

newtype Foo = Foo (Int, String) deriving (Generic)
instance Wrapped Foo
Run Code Online (Sandbox Code Playgroud)

然后可以写:

bar :: Lens' Foo Int
bar = _Wrapped' . _1
Run Code Online (Sandbox Code Playgroud)