content: -- | @TemplateHaskell@ utilities for generating lens fields.
  
  module Extended.Lens.TH
         ( fieldsVerboseLensRules
         ) where
  
  import           Universum
  
  import           Data.Char                  (toUpper)
  import           Data.List                  (stripPrefix)
  import           Language.Haskell.TH.Syntax (Name, mkName, nameBase)
  import           Lens.Micro.Platform        (DefName (MethodName), LensRules,
                                               camelCaseFields, lensField, makeLensesWith)
  
  -- | A field namer for 'fieldsVerboseLensRules'.
  verboseFieldsNamer :: Name -> [Name] -> Name -> [DefName]
  verboseFieldsNamer _ _ fieldName = maybeToList $ do
      fieldUnprefixed@(x:xs) <- stripPrefix "_" (nameBase fieldName)
      let className  = "HasPoly" ++ toUpper x : xs
      let methodName = fieldUnprefixed
      pure (MethodName (mkName className) (mkName methodName))
  
  -- | Custom rules for generating lenses. This is similar to
  -- @makeFields@ but generated type classes have names like @HasPolyFoo@
  -- instead of @HasFoo@ so they supposed to be used by introducing new
  -- constraint aliases. See 'Importify.Environment' for details.
  fieldsVerboseLensRules :: LensRules
  fieldsVerboseLensRules = camelCaseFields & lensField .~ verboseFieldsNamer
  