{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE TypeSynonymInstances      #-}
{-# LANGUAGE FlexibleInstances         #-}
{-# LANGUAGE TupleSections             #-}
{-# LANGUAGE PatternSynonyms           #-}

module Language.Haskell.Liquid.GHC.Play where

import Prelude hiding (error)
import GHC
import CoreSyn
import Var
import DataCon

import TyCon
import PrelNames (isStringClassName)

import           Control.Arrow       ((***))
import qualified Data.HashMap.Strict as M
import qualified Data.List           as L

import Language.Haskell.Liquid.GHC.API as Ghc hiding (substTysWith)
import Language.Haskell.Liquid.GHC.Misc ()
import Language.Haskell.Liquid.Types.Errors


isRecursivenewTyCon :: TyCon -> Bool 
isRecursivenewTyCon :: TyCon -> Bool
isRecursivenewTyCon TyCon
c 
  | Bool -> Bool
not (TyCon -> Bool
isNewTyCon TyCon
c)
  = Bool
False 
isRecursivenewTyCon TyCon
c 
  = Type -> Bool
go Type
t 
  where 
    t :: Type
t = ([TyVar], Type) -> Type
forall a b. (a, b) -> b
snd (([TyVar], Type) -> Type) -> ([TyVar], Type) -> Type
forall a b. (a -> b) -> a -> b
$ TyCon -> ([TyVar], Type)
newTyConRhs TyCon
c
    go :: Type -> Bool
go (AppTy Type
t1 Type
t2)    = Type -> Bool
go Type
t1 Bool -> Bool -> Bool
|| Type -> Bool
go Type
t2 
    go (TyConApp TyCon
c' [Type]
ts) = TyCon
c TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
c' Bool -> Bool -> Bool
|| (Type -> Bool) -> [Type] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Type -> Bool
go [Type]
ts 
    go (ForAllTy TyCoVarBinder
_ Type
t1)  = Type -> Bool
go Type
t1 
    go (FunTy AnonArgFlag
_ Type
t1 Type
t2)  = Type -> Bool
go Type
t1 Bool -> Bool -> Bool
|| Type -> Bool
go Type
t2
    go (CastTy Type
t1 KindCoercion
_)    = Type -> Bool
go Type
t1 
    go Type
_                = Bool
False   
  

isHoleVar :: Var -> Bool 
isHoleVar :: TyVar -> Bool
isHoleVar TyVar
x = [Char] -> [Char] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
L.isPrefixOf [Char]
"_" (TyVar -> [Char]
forall a. Show a => a -> [Char]
show TyVar
x)

dataConImplicitIds :: DataCon -> [Id]
dataConImplicitIds :: DataCon -> [TyVar]
dataConImplicitIds DataCon
dc = [ TyVar
x | AnId TyVar
x <- DataCon -> [TyThing]
dataConImplicitTyThings DataCon
dc]

class Subable a where
  sub   :: M.HashMap CoreBndr CoreExpr -> a -> a
  subTy :: M.HashMap TyVar Type -> a -> a

instance Subable CoreExpr where
  sub :: HashMap TyVar CoreExpr -> CoreExpr -> CoreExpr
sub HashMap TyVar CoreExpr
s (Var TyVar
v)        = CoreExpr -> TyVar -> HashMap TyVar CoreExpr -> CoreExpr
forall k v. (Eq k, Hashable k) => v -> k -> HashMap k v -> v
M.lookupDefault (TyVar -> CoreExpr
forall b. TyVar -> Expr b
Var TyVar
v) TyVar
v HashMap TyVar CoreExpr
s
  sub HashMap TyVar CoreExpr
_ (Lit Literal
l)        = Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
l
  sub HashMap TyVar CoreExpr
s (App CoreExpr
e1 CoreExpr
e2)    = CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App (HashMap TyVar CoreExpr -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar CoreExpr -> a -> a
sub HashMap TyVar CoreExpr
s CoreExpr
e1) (HashMap TyVar CoreExpr -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar CoreExpr -> a -> a
sub HashMap TyVar CoreExpr
s CoreExpr
e2)
  sub HashMap TyVar CoreExpr
s (Lam TyVar
b CoreExpr
e)      = TyVar -> CoreExpr -> CoreExpr
forall b. b -> Expr b -> Expr b
Lam TyVar
b (HashMap TyVar CoreExpr -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar CoreExpr -> a -> a
sub HashMap TyVar CoreExpr
s CoreExpr
e)
  sub HashMap TyVar CoreExpr
s (Let Bind TyVar
b CoreExpr
e)      = Bind TyVar -> CoreExpr -> CoreExpr
forall b. Bind b -> Expr b -> Expr b
Let (HashMap TyVar CoreExpr -> Bind TyVar -> Bind TyVar
forall a. Subable a => HashMap TyVar CoreExpr -> a -> a
sub HashMap TyVar CoreExpr
s Bind TyVar
b) (HashMap TyVar CoreExpr -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar CoreExpr -> a -> a
sub HashMap TyVar CoreExpr
s CoreExpr
e)
  sub HashMap TyVar CoreExpr
s (Case CoreExpr
e TyVar
b Type
t [Alt TyVar]
a) = CoreExpr -> TyVar -> Type -> [Alt TyVar] -> CoreExpr
forall b. Expr b -> b -> Type -> [Alt b] -> Expr b
Case (HashMap TyVar CoreExpr -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar CoreExpr -> a -> a
sub HashMap TyVar CoreExpr
s CoreExpr
e) (HashMap TyVar CoreExpr -> TyVar -> TyVar
forall a. Subable a => HashMap TyVar CoreExpr -> a -> a
sub HashMap TyVar CoreExpr
s TyVar
b) Type
t ((Alt TyVar -> Alt TyVar) -> [Alt TyVar] -> [Alt TyVar]
forall a b. (a -> b) -> [a] -> [b]
map (HashMap TyVar CoreExpr -> Alt TyVar -> Alt TyVar
forall a. Subable a => HashMap TyVar CoreExpr -> a -> a
sub HashMap TyVar CoreExpr
s) [Alt TyVar]
a)
  sub HashMap TyVar CoreExpr
s (Cast CoreExpr
e KindCoercion
c)     = CoreExpr -> KindCoercion -> CoreExpr
forall b. Expr b -> KindCoercion -> Expr b
Cast (HashMap TyVar CoreExpr -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar CoreExpr -> a -> a
sub HashMap TyVar CoreExpr
s CoreExpr
e) KindCoercion
c
  sub HashMap TyVar CoreExpr
s (Tick Tickish TyVar
t CoreExpr
e)     = Tickish TyVar -> CoreExpr -> CoreExpr
forall b. Tickish TyVar -> Expr b -> Expr b
Tick Tickish TyVar
t (HashMap TyVar CoreExpr -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar CoreExpr -> a -> a
sub HashMap TyVar CoreExpr
s CoreExpr
e)
  sub HashMap TyVar CoreExpr
_ (Type Type
t)       = Type -> CoreExpr
forall b. Type -> Expr b
Type Type
t
  sub HashMap TyVar CoreExpr
_ (Coercion KindCoercion
c)   = KindCoercion -> CoreExpr
forall b. KindCoercion -> Expr b
Coercion KindCoercion
c

  subTy :: HashMap TyVar Type -> CoreExpr -> CoreExpr
subTy HashMap TyVar Type
s (Var TyVar
v)      = TyVar -> CoreExpr
forall b. TyVar -> Expr b
Var (HashMap TyVar Type -> TyVar -> TyVar
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s TyVar
v)
  subTy HashMap TyVar Type
_ (Lit Literal
l)      = Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
l
  subTy HashMap TyVar Type
s (App CoreExpr
e1 CoreExpr
e2)  = CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App (HashMap TyVar Type -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s CoreExpr
e1) (HashMap TyVar Type -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s CoreExpr
e2)
  subTy HashMap TyVar Type
s (Lam TyVar
b CoreExpr
e)    | TyVar -> Bool
isTyVar TyVar
b = TyVar -> CoreExpr -> CoreExpr
forall b. b -> Expr b -> Expr b
Lam TyVar
v' (HashMap TyVar Type -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s CoreExpr
e)
   where v' :: TyVar
v' = case TyVar -> HashMap TyVar Type -> Maybe Type
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
M.lookup TyVar
b HashMap TyVar Type
s of
               Just (TyVarTy TyVar
v) -> TyVar
v
               Maybe Type
_                -> TyVar
b

  subTy HashMap TyVar Type
s (Lam TyVar
b CoreExpr
e)      = TyVar -> CoreExpr -> CoreExpr
forall b. b -> Expr b -> Expr b
Lam (HashMap TyVar Type -> TyVar -> TyVar
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s TyVar
b) (HashMap TyVar Type -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s CoreExpr
e)
  subTy HashMap TyVar Type
s (Let Bind TyVar
b CoreExpr
e)      = Bind TyVar -> CoreExpr -> CoreExpr
forall b. Bind b -> Expr b -> Expr b
Let (HashMap TyVar Type -> Bind TyVar -> Bind TyVar
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s Bind TyVar
b) (HashMap TyVar Type -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s CoreExpr
e)
  subTy HashMap TyVar Type
s (Case CoreExpr
e TyVar
b Type
t [Alt TyVar]
a) = CoreExpr -> TyVar -> Type -> [Alt TyVar] -> CoreExpr
forall b. Expr b -> b -> Type -> [Alt b] -> Expr b
Case (HashMap TyVar Type -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s CoreExpr
e) (HashMap TyVar Type -> TyVar -> TyVar
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s TyVar
b) (HashMap TyVar Type -> Type -> Type
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s Type
t) ((Alt TyVar -> Alt TyVar) -> [Alt TyVar] -> [Alt TyVar]
forall a b. (a -> b) -> [a] -> [b]
map (HashMap TyVar Type -> Alt TyVar -> Alt TyVar
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s) [Alt TyVar]
a)
  subTy HashMap TyVar Type
s (Cast CoreExpr
e KindCoercion
c)     = CoreExpr -> KindCoercion -> CoreExpr
forall b. Expr b -> KindCoercion -> Expr b
Cast (HashMap TyVar Type -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s CoreExpr
e) (HashMap TyVar Type -> KindCoercion -> KindCoercion
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s KindCoercion
c)
  subTy HashMap TyVar Type
s (Tick Tickish TyVar
t CoreExpr
e)     = Tickish TyVar -> CoreExpr -> CoreExpr
forall b. Tickish TyVar -> Expr b -> Expr b
Tick Tickish TyVar
t (HashMap TyVar Type -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s CoreExpr
e)
  subTy HashMap TyVar Type
s (Type Type
t)       = Type -> CoreExpr
forall b. Type -> Expr b
Type (HashMap TyVar Type -> Type -> Type
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s Type
t)
  subTy HashMap TyVar Type
s (Coercion KindCoercion
c)   = KindCoercion -> CoreExpr
forall b. KindCoercion -> Expr b
Coercion (HashMap TyVar Type -> KindCoercion -> KindCoercion
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s KindCoercion
c)

instance Subable Coercion where
  sub :: HashMap TyVar CoreExpr -> KindCoercion -> KindCoercion
sub HashMap TyVar CoreExpr
_ KindCoercion
c                = KindCoercion
c
  subTy :: HashMap TyVar Type -> KindCoercion -> KindCoercion
subTy HashMap TyVar Type
_ KindCoercion
_              = Maybe SrcSpan -> [Char] -> KindCoercion
forall a. Maybe SrcSpan -> [Char] -> a
panic Maybe SrcSpan
forall a. Maybe a
Nothing [Char]
"subTy Coercion"

instance Subable (Alt Var) where
 sub :: HashMap TyVar CoreExpr -> Alt TyVar -> Alt TyVar
sub HashMap TyVar CoreExpr
s (AltCon
a, [TyVar]
b, CoreExpr
e)   = (AltCon
a, (TyVar -> TyVar) -> [TyVar] -> [TyVar]
forall a b. (a -> b) -> [a] -> [b]
map (HashMap TyVar CoreExpr -> TyVar -> TyVar
forall a. Subable a => HashMap TyVar CoreExpr -> a -> a
sub HashMap TyVar CoreExpr
s) [TyVar]
b,   HashMap TyVar CoreExpr -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar CoreExpr -> a -> a
sub HashMap TyVar CoreExpr
s CoreExpr
e)
 subTy :: HashMap TyVar Type -> Alt TyVar -> Alt TyVar
subTy HashMap TyVar Type
s (AltCon
a, [TyVar]
b, CoreExpr
e) = (AltCon
a, (TyVar -> TyVar) -> [TyVar] -> [TyVar]
forall a b. (a -> b) -> [a] -> [b]
map (HashMap TyVar Type -> TyVar -> TyVar
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s) [TyVar]
b, HashMap TyVar Type -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s CoreExpr
e)

instance Subable Var where
 sub :: HashMap TyVar CoreExpr -> TyVar -> TyVar
sub HashMap TyVar CoreExpr
s TyVar
v   | TyVar -> HashMap TyVar CoreExpr -> Bool
forall k a. (Eq k, Hashable k) => k -> HashMap k a -> Bool
M.member TyVar
v HashMap TyVar CoreExpr
s = CoreExpr -> TyVar
forall t. Expr t -> TyVar
subVar (CoreExpr -> TyVar) -> CoreExpr -> TyVar
forall a b. (a -> b) -> a -> b
$ HashMap TyVar CoreExpr
s HashMap TyVar CoreExpr -> TyVar -> CoreExpr
forall k v.
(Eq k, Hashable k, HasCallStack) =>
HashMap k v -> k -> v
M.! TyVar
v
           | Bool
otherwise    = TyVar
v
 subTy :: HashMap TyVar Type -> TyVar -> TyVar
subTy HashMap TyVar Type
s TyVar
v = TyVar -> Type -> TyVar
setVarType TyVar
v (HashMap TyVar Type -> Type -> Type
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s (TyVar -> Type
varType TyVar
v))

subVar :: Expr t -> Id
subVar :: Expr t -> TyVar
subVar (Var TyVar
x) = TyVar
x
subVar  Expr t
_      = Maybe SrcSpan -> [Char] -> TyVar
forall a. Maybe SrcSpan -> [Char] -> a
panic Maybe SrcSpan
forall a. Maybe a
Nothing [Char]
"sub Var"

instance Subable (Bind Var) where
 sub :: HashMap TyVar CoreExpr -> Bind TyVar -> Bind TyVar
sub HashMap TyVar CoreExpr
s (NonRec TyVar
x CoreExpr
e)   = TyVar -> CoreExpr -> Bind TyVar
forall b. b -> Expr b -> Bind b
NonRec (HashMap TyVar CoreExpr -> TyVar -> TyVar
forall a. Subable a => HashMap TyVar CoreExpr -> a -> a
sub HashMap TyVar CoreExpr
s TyVar
x) (HashMap TyVar CoreExpr -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar CoreExpr -> a -> a
sub HashMap TyVar CoreExpr
s CoreExpr
e)
 sub HashMap TyVar CoreExpr
s (Rec [(TyVar, CoreExpr)]
xes)      = [(TyVar, CoreExpr)] -> Bind TyVar
forall b. [(b, Expr b)] -> Bind b
Rec ((HashMap TyVar CoreExpr -> TyVar -> TyVar
forall a. Subable a => HashMap TyVar CoreExpr -> a -> a
sub HashMap TyVar CoreExpr
s (TyVar -> TyVar)
-> (CoreExpr -> CoreExpr) -> (TyVar, CoreExpr) -> (TyVar, CoreExpr)
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** HashMap TyVar CoreExpr -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar CoreExpr -> a -> a
sub HashMap TyVar CoreExpr
s) ((TyVar, CoreExpr) -> (TyVar, CoreExpr))
-> [(TyVar, CoreExpr)] -> [(TyVar, CoreExpr)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(TyVar, CoreExpr)]
xes)

 subTy :: HashMap TyVar Type -> Bind TyVar -> Bind TyVar
subTy HashMap TyVar Type
s (NonRec TyVar
x CoreExpr
e) = TyVar -> CoreExpr -> Bind TyVar
forall b. b -> Expr b -> Bind b
NonRec (HashMap TyVar Type -> TyVar -> TyVar
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s TyVar
x) (HashMap TyVar Type -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s CoreExpr
e)
 subTy HashMap TyVar Type
s (Rec [(TyVar, CoreExpr)]
xes)    = [(TyVar, CoreExpr)] -> Bind TyVar
forall b. [(b, Expr b)] -> Bind b
Rec ((HashMap TyVar Type -> TyVar -> TyVar
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s  (TyVar -> TyVar)
-> (CoreExpr -> CoreExpr) -> (TyVar, CoreExpr) -> (TyVar, CoreExpr)
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** HashMap TyVar Type -> CoreExpr -> CoreExpr
forall a. Subable a => HashMap TyVar Type -> a -> a
subTy HashMap TyVar Type
s) ((TyVar, CoreExpr) -> (TyVar, CoreExpr))
-> [(TyVar, CoreExpr)] -> [(TyVar, CoreExpr)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(TyVar, CoreExpr)]
xes)

instance Subable Type where
 sub :: HashMap TyVar CoreExpr -> Type -> Type
sub HashMap TyVar CoreExpr
_ Type
e   = Type
e
 subTy :: HashMap TyVar Type -> Type -> Type
subTy     = HashMap TyVar Type -> Type -> Type
substTysWith

substTysWith :: M.HashMap Var Type -> Type -> Type
substTysWith :: HashMap TyVar Type -> Type -> Type
substTysWith HashMap TyVar Type
s tv :: Type
tv@(TyVarTy TyVar
v)    = Type -> TyVar -> HashMap TyVar Type -> Type
forall k v. (Eq k, Hashable k) => v -> k -> HashMap k v -> v
M.lookupDefault Type
tv TyVar
v HashMap TyVar Type
s
substTysWith HashMap TyVar Type
s (FunTy AnonArgFlag
aaf Type
t1 Type
t2) = AnonArgFlag -> Type -> Type -> Type
FunTy AnonArgFlag
aaf (HashMap TyVar Type -> Type -> Type
substTysWith HashMap TyVar Type
s Type
t1) (HashMap TyVar Type -> Type -> Type
substTysWith HashMap TyVar Type
s Type
t2)
substTysWith HashMap TyVar Type
s (ForAllTy TyCoVarBinder
v Type
t)    = TyCoVarBinder -> Type -> Type
ForAllTy TyCoVarBinder
v (HashMap TyVar Type -> Type -> Type
substTysWith (TyVar -> HashMap TyVar Type -> HashMap TyVar Type
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> HashMap k v
M.delete (TyCoVarBinder -> TyVar
forall tv argf. VarBndr tv argf -> tv
binderVar TyCoVarBinder
v) HashMap TyVar Type
s) Type
t)
substTysWith HashMap TyVar Type
s (TyConApp TyCon
c [Type]
ts)   = TyCon -> [Type] -> Type
TyConApp TyCon
c ((Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (HashMap TyVar Type -> Type -> Type
substTysWith HashMap TyVar Type
s) [Type]
ts)
substTysWith HashMap TyVar Type
s (AppTy Type
t1 Type
t2)     = Type -> Type -> Type
AppTy (HashMap TyVar Type -> Type -> Type
substTysWith HashMap TyVar Type
s Type
t1) (HashMap TyVar Type -> Type -> Type
substTysWith HashMap TyVar Type
s Type
t2)
substTysWith HashMap TyVar Type
_ (LitTy TyLit
t)         = TyLit -> Type
LitTy TyLit
t
substTysWith HashMap TyVar Type
s (CastTy Type
t KindCoercion
c)      = Type -> KindCoercion -> Type
CastTy (HashMap TyVar Type -> Type -> Type
substTysWith HashMap TyVar Type
s Type
t) KindCoercion
c
substTysWith HashMap TyVar Type
_ (CoercionTy KindCoercion
c)    = KindCoercion -> Type
CoercionTy KindCoercion
c 

substExpr :: M.HashMap Var Var -> CoreExpr -> CoreExpr
substExpr :: HashMap TyVar TyVar -> CoreExpr -> CoreExpr
substExpr HashMap TyVar TyVar
s = CoreExpr -> CoreExpr
go 
  where
    subsVar :: TyVar -> TyVar
subsVar TyVar
v                = TyVar -> TyVar -> HashMap TyVar TyVar -> TyVar
forall k v. (Eq k, Hashable k) => v -> k -> HashMap k v -> v
M.lookupDefault TyVar
v TyVar
v HashMap TyVar TyVar
s
    go :: CoreExpr -> CoreExpr
go (Var TyVar
v)               = TyVar -> CoreExpr
forall b. TyVar -> Expr b
Var (TyVar -> CoreExpr) -> TyVar -> CoreExpr
forall a b. (a -> b) -> a -> b
$ TyVar -> TyVar
subsVar TyVar
v
    go (Lit Literal
l)               = Literal -> CoreExpr
forall b. Literal -> Expr b
Lit Literal
l 
    go (App CoreExpr
e1 CoreExpr
e2)           = CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App (CoreExpr -> CoreExpr
go CoreExpr
e1) (CoreExpr -> CoreExpr
go CoreExpr
e2) 
    go (Lam TyVar
x CoreExpr
e)             = TyVar -> CoreExpr -> CoreExpr
forall b. b -> Expr b -> Expr b
Lam (TyVar -> TyVar
subsVar TyVar
x) (CoreExpr -> CoreExpr
go CoreExpr
e)
    go (Let (NonRec TyVar
x CoreExpr
ex) CoreExpr
e) = Bind TyVar -> CoreExpr -> CoreExpr
forall b. Bind b -> Expr b -> Expr b
Let (TyVar -> CoreExpr -> Bind TyVar
forall b. b -> Expr b -> Bind b
NonRec (TyVar -> TyVar
subsVar TyVar
x) (CoreExpr -> CoreExpr
go CoreExpr
ex)) (CoreExpr -> CoreExpr
go CoreExpr
e) 
    go (Let (Rec [(TyVar, CoreExpr)]
xes) CoreExpr
e)     = Bind TyVar -> CoreExpr -> CoreExpr
forall b. Bind b -> Expr b -> Expr b
Let ([(TyVar, CoreExpr)] -> Bind TyVar
forall b. [(b, Expr b)] -> Bind b
Rec [(TyVar -> TyVar
subsVar TyVar
x, CoreExpr -> CoreExpr
go CoreExpr
e) | (TyVar
x,CoreExpr
e) <- [(TyVar, CoreExpr)]
xes]) (CoreExpr -> CoreExpr
go CoreExpr
e)
    go (Case CoreExpr
e TyVar
b Type
t [Alt TyVar]
alts)     = CoreExpr -> TyVar -> Type -> [Alt TyVar] -> CoreExpr
forall b. Expr b -> b -> Type -> [Alt b] -> Expr b
Case (CoreExpr -> CoreExpr
go CoreExpr
e) (TyVar -> TyVar
subsVar TyVar
b) Type
t [(AltCon
c, TyVar -> TyVar
subsVar (TyVar -> TyVar) -> [TyVar] -> [TyVar]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [TyVar]
xs, CoreExpr -> CoreExpr
go CoreExpr
e) | (AltCon
c, [TyVar]
xs, CoreExpr
e) <- [Alt TyVar]
alts]
    go (Cast CoreExpr
e KindCoercion
c)            = CoreExpr -> KindCoercion -> CoreExpr
forall b. Expr b -> KindCoercion -> Expr b
Cast (CoreExpr -> CoreExpr
go CoreExpr
e) KindCoercion
c 
    go (Tick Tickish TyVar
t CoreExpr
e)            = Tickish TyVar -> CoreExpr -> CoreExpr
forall b. Tickish TyVar -> Expr b -> Expr b
Tick Tickish TyVar
t (CoreExpr -> CoreExpr
go CoreExpr
e)
    go (Type Type
t)              = Type -> CoreExpr
forall b. Type -> Expr b
Type Type
t 
    go (Coercion KindCoercion
c)          = KindCoercion -> CoreExpr
forall b. KindCoercion -> Expr b
Coercion KindCoercion
c 

mapType :: (Type -> Type) -> Type -> Type
mapType :: (Type -> Type) -> Type -> Type
mapType Type -> Type
f = Type -> Type
go
  where
    go :: Type -> Type
go t :: Type
t@(TyVarTy TyVar
_)      = Type -> Type
f Type
t
    go (AppTy Type
t1 Type
t2)      = Type -> Type
f (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$ Type -> Type -> Type
AppTy (Type -> Type
go Type
t1) (Type -> Type
go Type
t2)
    go (TyConApp TyCon
c [Type]
ts)    = Type -> Type
f (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$ TyCon -> [Type] -> Type
TyConApp TyCon
c (Type -> Type
go (Type -> Type) -> [Type] -> [Type]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Type]
ts)
    go (FunTy AnonArgFlag
aaf Type
t1 Type
t2)  = Type -> Type
f (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$ AnonArgFlag -> Type -> Type -> Type
FunTy AnonArgFlag
aaf (Type -> Type
go Type
t1) (Type -> Type
go Type
t2)
    go (ForAllTy TyCoVarBinder
v Type
t)     = Type -> Type
f (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$ TyCoVarBinder -> Type -> Type
ForAllTy TyCoVarBinder
v (Type -> Type
go Type
t)
    go t :: Type
t@(LitTy TyLit
_)        = Type -> Type
f Type
t
    go (CastTy Type
t KindCoercion
c)       = Type -> KindCoercion -> Type
CastTy (Type -> Type
go Type
t) KindCoercion
c
    go (CoercionTy KindCoercion
c)     = Type -> Type
f (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$ KindCoercion -> Type
CoercionTy KindCoercion
c 


stringClassArg :: Type -> Maybe Type
stringClassArg :: Type -> Maybe Type
stringClassArg Type
t | Type -> Bool
isFunTy Type
t 
  = Maybe Type
forall a. Maybe a
Nothing
stringClassArg Type
t
  = case (Type -> Maybe TyCon
tyConAppTyCon_maybe Type
t, Type -> Maybe [Type]
tyConAppArgs_maybe Type
t) of
      (Just TyCon
c, Just [Type
t]) | Name
isStringClassName Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon -> Name
tyConName TyCon
c
           -> Type -> Maybe Type
forall a. a -> Maybe a
Just Type
t
      (Maybe TyCon, Maybe [Type])
_    -> Maybe Type
forall a. Maybe a
Nothing