{-# LANGUAGE CPP #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeFamilies #-}
module Retrie.Rewrites.Types where
import Control.Monad
import Data.Maybe
import Retrie.ExactPrint
import Retrie.Expr
import Retrie.GHC
import Retrie.Quantifiers
import Retrie.Types
import Retrie.Util
typeSynonymsToRewrites
:: [(FastString, Direction)]
-> AnnotatedModule
-> IO (UniqFM [Rewrite (LHsType GhcPs)])
typeSynonymsToRewrites specs am = fmap astA $ transformA am $ \ m -> do
let
fsMap = uniqBag specs
tySyns =
[ (rdr, (dir, (nm, hsq_explicit vars, rhs)))
#if __GLASGOW_HASKELL__ < 806
| L _ (TyClD (SynDecl nm vars _ rhs _)) <- hsmodDecls $ unLoc m
#else
| L _ (TyClD _ (SynDecl _ nm vars _ rhs)) <- hsmodDecls $ unLoc m
#endif
, let rdr = rdrFS (unLoc nm)
, dir <- fromMaybe [] (lookupUFM fsMap rdr)
]
fmap uniqBag $
forM tySyns $ \(rdr, args) -> (rdr,) <$> uncurry mkTypeRewrite args
mkTypeRewrite
:: Direction
-> (Located RdrName, [LHsTyVarBndr GhcPs], LHsType GhcPs)
-> TransformT IO (Rewrite (LHsType GhcPs))
mkTypeRewrite d (lhsName, vars, rhs) = do
setEntryDPT lhsName $ DP (0,0)
tc <- mkTyVar lhsName
let
lvs = tyBindersToLocatedRdrNames vars
args <- forM lvs $ \ lv -> do
tv <- mkTyVar lv
setEntryDPT tv (DP (0,1))
return tv
lhsApps <- mkHsAppsTy (tc:args)
let
(pat, tmp) = case d of
LeftToRight -> (lhsApps, rhs)
RightToLeft -> (rhs, lhsApps)
p <- pruneA pat
t <- pruneA tmp
return $ mkRewrite (mkQs $ map unLoc lvs) p t