+{-# LANGUAGE PatternGuards, TypeSynonymInstances #-}
-- | This module provides a number of functions to find out things about Core
-- programs. This module does not provide the actual plumbing to work with
-- Core and Haskell (it uses HsTools for this), but only the functions that
import qualified RdrName
import qualified Name
import qualified OccName
+import qualified Type
+import qualified Id
+import qualified TyCon
import qualified TysWiredIn
import qualified Bag
import qualified DynFlags
-- Automatically import modules for any fully qualified identifiers
setDynFlag DynFlags.Opt_ImplicitImportQualified
- let from_int_t_name = mkRdrName "Types.Data.Num" "fromIntegerT"
+ let from_int_t_name = mkRdrName "Types.Data.Num.Ops" "fromIntegerT"
let from_int_t = SrcLoc.noLoc $ HsExpr.HsVar from_int_t_name
let undef = hsTypedUndef $ coreToHsType ty
let app = SrcLoc.noLoc $ HsExpr.HsApp (from_int_t) (undef)
has_free_vars :: CoreSyn.CoreExpr -> Bool
has_free_vars = not . VarSet.isEmptyVarSet . CoreFVs.exprFreeVars
+-- Does the given expression use any of the given binders?
+expr_uses_binders :: [CoreSyn.CoreBndr] -> CoreSyn.CoreExpr -> Bool
+expr_uses_binders bndrs = not . VarSet.isEmptyVarSet . (CoreFVs.exprSomeFreeVars (`elem` bndrs))
+
-- Turns a Var CoreExpr into the Id inside it. Will of course only work for
-- simple Var CoreExprs, not complexer ones.
exprToVar :: CoreSyn.CoreExpr -> Var.Id
(CoreSyn.Var f, args) = CoreSyn.collectArgs app
literals = filter (is_lit) args
--- reduceCoreListToHsList :: CoreExpr -> [a]
+reduceCoreListToHsList :: CoreSyn.CoreExpr -> [CoreSyn.CoreExpr]
reduceCoreListToHsList app@(CoreSyn.App _ _) = out
where
(fun, args) = CoreSyn.collectArgs app
otherwise -> []
reduceCoreListToHsList _ = []
+
+-- | Is the given type a State type?
+isStateType :: Type.Type -> Bool
+-- Resolve any type synonyms remaining
+isStateType ty | Just ty' <- Type.tcView ty = isStateType ty'
+isStateType ty = Maybe.isJust $ do
+ -- Split the type. Don't use normal splitAppTy, since that looks through
+ -- newtypes, and we want to see the State newtype.
+ (typef, _) <- Type.repSplitAppTy_maybe ty
+ -- See if the applied type is a type constructor
+ (tycon, _) <- Type.splitTyConApp_maybe typef
+ if TyCon.isNewTyCon tycon && Name.getOccString tycon == "State"
+ then
+ Just ()
+ else
+ Nothing
+
+-- | Does the given TypedThing have a State type?
+hasStateType :: (TypedThing t) => t -> Bool
+hasStateType expr = case getType expr of
+ Nothing -> False
+ Just ty -> isStateType ty
+
+
+-- | A class of things that (optionally) have a core Type. The type is
+-- optional, since Type expressions don't have a type themselves.
+class TypedThing t where
+ getType :: t -> Maybe Type.Type
+
+instance TypedThing CoreSyn.CoreExpr where
+ getType (CoreSyn.Type _) = Nothing
+ getType expr = Just $ CoreUtils.exprType expr
+
+instance TypedThing CoreSyn.CoreBndr where
+ getType = return . Id.idType
+
+instance TypedThing Type.Type where
+ getType = return . id