deriveAnnOne :: Info -> Q Dec
deriveAnnOne i =
  case i of
    TyConI (DataD dcx n vsk cons _) ->
      annInstance dcx n (map unTyVarBndr vsk) (map doCons cons)
    TyConI (NewtypeD dcx n vsk con _) ->
      annInstance dcx n (map unTyVarBndr vsk) [doCons con]
    _ -> error (modName ++ ".deriveAnn: unhandled: " ++ pprint i)
  where annInstance _ _ [] _ = error (modName ++ ".annInstance: unhandled " ++ pprint i)
        annInstance dcx n vs cases =
            let (anns, amaps) = unzip cases
            in instanceD (ctxt dcx (init vs)) (conT ''Annotated `appT` typ n (init vs)) [funD 'ann anns, funD 'amap amaps]
        typ n = foldl appT (conT n) . map varT
        ctxt dcx = fmap (dcx ++) . cxt . map annPred
        unTyVarBndr (PlainTV v) = v
        unTyVarBndr (KindedTV v _) = v
        annPred n = classP ''Annotated [varT n]
deriveAnnOne :: Info -> Q Dec
deriveAnnOne i =
  case i of
    TyConI (DataD dcx n vsk cons _) ->
      annInstance dcx n (map unTyVarBndr vsk) (map doCons cons)
    TyConI (NewtypeD dcx n vsk con _) ->
      annInstance dcx n (map unTyVarBndr vsk) [doCons con]
    _ -> error (modName ++ ".deriveAnn: unhandled: " ++ pprint i)
  where annInstance _ _ [] _ = error (modName ++ ".annInstance: unhandled " ++ pprint i)
        annInstance dcx n vs cases =
            let (anns, amaps) = unzip cases
            in instanceD (ctxt dcx (init vs)) (conT ''Annotated `appT` typ n (init vs)) [funD 'ann anns, funD 'amap amaps]
        typ n = foldl appT (conT n) . map varT
        ctxt dcx = fmap (dcx ++) . cxt . map annPred
        unTyVarBndr (PlainTV v) = v
        unTyVarBndr (KindedTV v _) = v
        annPred n = classP ''Annotated [varT n]
deriveAnnOne i =
  case i of
    TyConI (DataD dcx n vsk cons _) ->
      annInstance dcx n (map unTyVarBndr vsk) (map doCons cons)
    TyConI (NewtypeD dcx n vsk con _) ->
      annInstance dcx n (map unTyVarBndr vsk) [doCons con]
    _ -> error (modName ++ ".deriveAnn: unhandled: " ++ pprint i)
  where annInstance _ _ [] _ = error (modName ++ ".annInstance: unhandled " ++ pprint i)
        annInstance dcx n vs cases =
            let (anns, amaps) = unzip cases
            in instanceD (ctxt dcx (init vs)) (conT ''Annotated `appT` typ n (init vs)) [funD 'ann anns, funD 'amap amaps]
        typ n = foldl appT (conT n) . map varT
        ctxt dcx = fmap (dcx ++) . cxt . map annPred
        unTyVarBndr (PlainTV v) = v
        unTyVarBndr (KindedTV v _) = v
        annPred n = classP ''Annotated [varT n]