Open DanBurton opened 12 years ago
This is quite a daunting task; I'm not going to work on it for a while (indefinitely), but I still think this functionality should be available.
Is there any hope of borrowing code from lens? The TH there is not exactly... simple, let's say, but perhaps someone already familiar with it could help porting it for lens-family?
It's absolutely possible. Fun fact: lens TH code was initially forked from lens-family-th. Then the lens code got enhanced and rewritten with tons more features. And in turn, lens-family-th code was inspired by some other package' TH. I think it was fclabels.
TH isn't complicated, it's just cumbersome and verbose. Almost anyone could do this task, but it's just not very fun to do.
You should make the type signatures optional. The reason why is that if you provide type signatures for auto-generated lenses then there is no way for users to add haddocks for those generated lenses. They won't have a type signature to attach the documentation to, since if they write their own type signature it will conflict with the one you generated.
I just ran into the lack of generated type signatures since I always have warnings turned on.
BTW, what would be the best way to make type signatures optional (once implemented)? Something like makeLensesWithoutSignatures
?
Usually I work around this by adding {-# OPTIONS_GHC -fno-warn-missing-signatures #-}
to the top of my types modules if I don't feel like adding documentation to the auto-generated lenses.
I think I'll go for partial compatibility with the lens library and make a config data type to describe options such as this.
I'm actually tempted to work with lens contributors to see if we can gut out some of the basic lens TH and share it between lens and lens-family-th. Then each would add its own type signature layer on top.
I don't personally use this library very much, so as you can see, I've let this issue sit for years. I'll try to promptly respond to PRs, if anyone is interested in writing this feature.
For lenses that don't change the type, I think this works.
deriveLensSig :: Name -> LensTypeInfo -> ConstructorFieldInfo -> Q [Dec]
deriveLensSig name (tyName, tyVars) (fldName, _, fldType) = do
let src = foldl AppT (ConT tyName) (map var tyVars)
where var (PlainTV n) = VarT n
var (KindedTV n _) = VarT n
lensT s d = AppT (AppT (ConT ''Lens') s) d
sig = SigD name (lensT src fldType)
return [sig]
Currently, the implementations for
deriveLensSig
remain stubbed, and provide no type signature. These should be filled out to create an appropriate type signature. Ideally, the type signature should be in terms of the correspondingLens.Family
orLens.Family2
type.