module Curry.FlatCurry.Goodies where
import Curry.FlatCurry.Type
type Update a b = (b -> b) -> a -> a
trProg :: (String -> [String] -> [TypeDecl] -> [FuncDecl] -> [OpDecl] -> a)
-> Prog -> a
trProg prog (Prog name imps types funcs ops) = prog name imps types funcs ops
progName :: Prog -> String
progName = trProg (\name _ _ _ _ -> name)
progImports :: Prog -> [String]
progImports = trProg (\_ imps _ _ _ -> imps)
progTypes :: Prog -> [TypeDecl]
progTypes = trProg (\_ _ types _ _ -> types)
progFuncs :: Prog -> [FuncDecl]
progFuncs = trProg (\_ _ _ funcs _ -> funcs)
progOps :: Prog -> [OpDecl]
progOps = trProg (\_ _ _ _ ops -> ops)
updProg :: (String -> String) ->
([String] -> [String]) ->
([TypeDecl] -> [TypeDecl]) ->
([FuncDecl] -> [FuncDecl]) ->
([OpDecl] -> [OpDecl]) -> Prog -> Prog
updProg fn fi ft ff fo = trProg prog
where
prog name imps types funcs ops
= Prog (fn name) (fi imps) (ft types) (ff funcs) (fo ops)
updProgName :: Update Prog String
updProgName f = updProg f id id id id
updProgImports :: Update Prog [String]
updProgImports f = updProg id f id id id
updProgTypes :: Update Prog [TypeDecl]
updProgTypes f = updProg id id f id id
updProgFuncs :: Update Prog [FuncDecl]
updProgFuncs f = updProg id id id f id
updProgOps :: Update Prog [OpDecl]
updProgOps = updProg id id id id
allVarsInProg :: Prog -> [VarIndex]
allVarsInProg = concatMap allVarsInFunc . progFuncs
updProgExps :: Update Prog Expr
updProgExps = updProgFuncs . map . updFuncBody
rnmAllVarsInProg :: Update Prog VarIndex
rnmAllVarsInProg = updProgFuncs . map . rnmAllVarsInFunc
updQNamesInProg :: Update Prog QName
updQNamesInProg f = updProg id id
(map (updQNamesInType f)) (map (updQNamesInFunc f)) (map (updOpName f))
rnmProg :: String -> Prog -> Prog
rnmProg name p = updProgName (const name) (updQNamesInProg rnm p)
where
rnm (m,n) | m==progName p = (name,n)
| otherwise = (m,n)
trType :: (QName -> Visibility -> [TVarIndex] -> [ConsDecl] -> a) ->
(QName -> Visibility -> [TVarIndex] -> TypeExpr -> a) -> TypeDecl -> a
trType typ _ (Type name vis params cs) = typ name vis params cs
trType _ typesyn (TypeSyn name vis params syn) = typesyn name vis params syn
typeName :: TypeDecl -> QName
typeName = trType (\name _ _ _ -> name) (\name _ _ _ -> name)
typeVisibility :: TypeDecl -> Visibility
typeVisibility = trType (\_ vis _ _ -> vis) (\_ vis _ _ -> vis)
typeParams :: TypeDecl -> [TVarIndex]
typeParams = trType (\_ _ params _ -> params) (\_ _ params _ -> params)
typeConsDecls :: TypeDecl -> [ConsDecl]
typeConsDecls = trType (\_ _ _ cs -> cs)
(error "Curry.FlatCurry.Goodies: type synonym")
typeSyn :: TypeDecl -> TypeExpr
typeSyn = trType undefined (\_ _ _ syn -> syn)
isTypeSyn :: TypeDecl -> Bool
isTypeSyn = trType (\_ _ _ _ -> False) (\_ _ _ _ -> True)
isDataTypeDecl :: TypeDecl -> Bool
isDataTypeDecl = trType (\_ _ _ cs -> not (null cs)) (\_ _ _ _ -> False)
isExternalType :: TypeDecl -> Bool
isExternalType = trType (\_ _ _ cs -> null cs) (\_ _ _ _ -> False)
isPublicType :: TypeDecl -> Bool
isPublicType = (== Public) . typeVisibility
updType :: (QName -> QName) ->
(Visibility -> Visibility) ->
([TVarIndex] -> [TVarIndex]) ->
([ConsDecl] -> [ConsDecl]) ->
(TypeExpr -> TypeExpr) -> TypeDecl -> TypeDecl
updType fn fv fp fc fs = trType typ typesyn
where
typ name vis params cs = Type (fn name) (fv vis) (fp params) (fc cs)
typesyn name vis params syn = TypeSyn (fn name) (fv vis) (fp params) (fs syn)
updTypeName :: Update TypeDecl QName
updTypeName f = updType f id id id id
updTypeVisibility :: Update TypeDecl Visibility
updTypeVisibility f = updType id f id id id
updTypeParams :: Update TypeDecl [TVarIndex]
updTypeParams f = updType id id f id id
updTypeConsDecls :: Update TypeDecl [ConsDecl]
updTypeConsDecls f = updType id id id f id
updTypeSynonym :: Update TypeDecl TypeExpr
updTypeSynonym = updType id id id id
updQNamesInType :: Update TypeDecl QName
updQNamesInType f
= updType f id id (map (updQNamesInConsDecl f)) (updQNamesInTypeExpr f)
trCons :: (QName -> Int -> Visibility -> [TypeExpr] -> a) -> ConsDecl -> a
trCons cons (Cons name arity vis args) = cons name arity vis args
consName :: ConsDecl -> QName
consName = trCons (\name _ _ _ -> name)
consArity :: ConsDecl -> Int
consArity = trCons (\_ arity _ _ -> arity)
consVisibility :: ConsDecl -> Visibility
consVisibility = trCons (\_ _ vis _ -> vis)
isPublicCons :: ConsDecl -> Bool
isPublicCons = isPublic . consVisibility
consArgs :: ConsDecl -> [TypeExpr]
consArgs = trCons (\_ _ _ args -> args)
updCons :: (QName -> QName) ->
(Int -> Int) ->
(Visibility -> Visibility) ->
([TypeExpr] -> [TypeExpr]) -> ConsDecl -> ConsDecl
updCons fn fa fv fas = trCons cons
where
cons name arity vis args = Cons (fn name) (fa arity) (fv vis) (fas args)
updConsName :: Update ConsDecl QName
updConsName f = updCons f id id id
updConsArity :: Update ConsDecl Int
updConsArity f = updCons id f id id
updConsVisibility :: Update ConsDecl Visibility
updConsVisibility f = updCons id id f id
updConsArgs :: Update ConsDecl [TypeExpr]
updConsArgs = updCons id id id
updQNamesInConsDecl :: Update ConsDecl QName
updQNamesInConsDecl f = updCons f id id (map (updQNamesInTypeExpr f))
tVarIndex :: TypeExpr -> TVarIndex
tVarIndex (TVar n) = n
tVarIndex _ = error $ "Curry.FlatCurry.Goodies.tvarIndex: " ++
"no type variable"
domain :: TypeExpr -> TypeExpr
domain (FuncType dom _) = dom
domain _ = error $ "Curry.FlatCurry.Goodies.domain: " ++
"no function type"
range :: TypeExpr -> TypeExpr
range (FuncType _ ran) = ran
range _ = error $ "Curry.FlatCurry.Goodies.range: " ++
"no function type"
tConsName :: TypeExpr -> QName
tConsName (TCons name _) = name
tConsName _ = error $ "Curry.FlatCurry.Goodies.tConsName: " ++
"no constructor type"
tConsArgs :: TypeExpr -> [TypeExpr]
tConsArgs (TCons _ args) = args
tConsArgs _ = error $ "Curry.FlatCurry.Goodies.tConsArgs: " ++
"no constructor type"
trTypeExpr :: (TVarIndex -> a) ->
(QName -> [a] -> a) ->
(a -> a -> a) ->
([TVarIndex] -> a -> a) -> TypeExpr -> a
trTypeExpr tvar _ _ _ (TVar n) = tvar n
trTypeExpr tvar tcons functype foralltype (TCons name args)
= tcons name (map (trTypeExpr tvar tcons functype foralltype) args)
trTypeExpr tvar tcons functype foralltype (FuncType from to)
= functype (f from) (f to)
where
f = trTypeExpr tvar tcons functype foralltype
trTypeExpr tvar tcons functype foralltype (ForallType ns t)
= foralltype ns (trTypeExpr tvar tcons functype foralltype t)
isTVar :: TypeExpr -> Bool
isTVar = trTypeExpr (\_ -> True) (\_ _ -> False) (\_ _ -> False) (\_ _ -> False)
isTCons :: TypeExpr -> Bool
isTCons
= trTypeExpr (\_ -> False) (\_ _ -> True) (\_ _ -> False) (\_ _ -> False)
isFuncType :: TypeExpr -> Bool
isFuncType
= trTypeExpr (\_ -> False) (\_ _ -> False) (\_ _ -> True) (\_ _ -> False)
isForallType :: TypeExpr -> Bool
isForallType
= trTypeExpr (\_ -> False) (\_ _ -> False) (\_ _ -> False) (\_ _ -> True)
updTVars :: (TVarIndex -> TypeExpr) -> TypeExpr -> TypeExpr
updTVars tvar = trTypeExpr tvar TCons FuncType ForallType
updTCons :: (QName -> [TypeExpr] -> TypeExpr) -> TypeExpr -> TypeExpr
updTCons tcons = trTypeExpr TVar tcons FuncType ForallType
updFuncTypes :: (TypeExpr -> TypeExpr -> TypeExpr) -> TypeExpr -> TypeExpr
updFuncTypes functype = trTypeExpr TVar TCons functype ForallType
updForallTypes :: ([TVarIndex] -> TypeExpr -> TypeExpr) -> TypeExpr -> TypeExpr
updForallTypes = trTypeExpr TVar TCons FuncType
argTypes :: TypeExpr -> [TypeExpr]
argTypes (TVar _) = []
argTypes (TCons _ _) = []
argTypes (FuncType dom ran) = dom : argTypes ran
argTypes (ForallType _ _) = []
typeArity :: TypeExpr -> Int
typeArity = length . argTypes
resultType :: TypeExpr -> TypeExpr
resultType (TVar n) = TVar n
resultType (TCons name args) = TCons name args
resultType (FuncType _ ran) = resultType ran
resultType (ForallType ns t) = ForallType ns t
allVarsInTypeExpr :: TypeExpr -> [TVarIndex]
allVarsInTypeExpr = trTypeExpr (:[]) (const concat) (++) (++)
allTypeCons :: TypeExpr -> [QName]
allTypeCons (TVar _) = []
allTypeCons (TCons name args) = name : concatMap allTypeCons args
allTypeCons (FuncType t1 t2) = allTypeCons t1 ++ allTypeCons t2
allTypeCons (ForallType _ t) = allTypeCons t
rnmAllVarsInTypeExpr :: (TVarIndex -> TVarIndex) -> TypeExpr -> TypeExpr
rnmAllVarsInTypeExpr f = updTVars (TVar . f)
updQNamesInTypeExpr :: (QName -> QName) -> TypeExpr -> TypeExpr
updQNamesInTypeExpr f = updTCons (\name args -> TCons (f name) args)
trOp :: (QName -> Fixity -> Integer -> a) -> OpDecl -> a
trOp op (Op name fix prec) = op name fix prec
opName :: OpDecl -> QName
opName = trOp (\name _ _ -> name)
opFixity :: OpDecl -> Fixity
opFixity = trOp (\_ fix _ -> fix)
opPrecedence :: OpDecl -> Integer
opPrecedence = trOp (\_ _ prec -> prec)
updOp :: (QName -> QName) ->
(Fixity -> Fixity) ->
(Integer -> Integer) -> OpDecl -> OpDecl
updOp fn ff fp = trOp op
where op name fix prec = Op (fn name) (ff fix) (fp prec)
updOpName :: Update OpDecl QName
updOpName f = updOp f id id
updOpFixity :: Update OpDecl Fixity
updOpFixity f = updOp id f id
updOpPrecedence :: Update OpDecl Integer
updOpPrecedence = updOp id id
trFunc :: (QName -> Int -> Visibility -> TypeExpr -> Rule -> a) -> FuncDecl -> a
trFunc func (Func name arity vis t rule) = func name arity vis t rule
funcName :: FuncDecl -> QName
funcName = trFunc (\name _ _ _ _ -> name)
funcArity :: FuncDecl -> Int
funcArity = trFunc (\_ arity _ _ _ -> arity)
funcVisibility :: FuncDecl -> Visibility
funcVisibility = trFunc (\_ _ vis _ _ -> vis)
funcType :: FuncDecl -> TypeExpr
funcType = trFunc (\_ _ _ t _ -> t)
funcRule :: FuncDecl -> Rule
funcRule = trFunc (\_ _ _ _ rule -> rule)
updFunc :: (QName -> QName) ->
(Int -> Int) ->
(Visibility -> Visibility) ->
(TypeExpr -> TypeExpr) ->
(Rule -> Rule) -> FuncDecl -> FuncDecl
updFunc fn fa fv ft fr = trFunc func
where
func name arity vis t rule
= Func (fn name) (fa arity) (fv vis) (ft t) (fr rule)
updFuncName :: Update FuncDecl QName
updFuncName f = updFunc f id id id id
updFuncArity :: Update FuncDecl Int
updFuncArity f = updFunc id f id id id
updFuncVisibility :: Update FuncDecl Visibility
updFuncVisibility f = updFunc id id f id id
updFuncType :: Update FuncDecl TypeExpr
updFuncType f = updFunc id id id f id
updFuncRule :: Update FuncDecl Rule
updFuncRule = updFunc id id id id
isPublicFunc :: FuncDecl -> Bool
isPublicFunc = isPublic . funcVisibility
isExternal :: FuncDecl -> Bool
isExternal = isRuleExternal . funcRule
allVarsInFunc :: FuncDecl -> [VarIndex]
allVarsInFunc = allVarsInRule . funcRule
funcArgs :: FuncDecl -> [VarIndex]
funcArgs = ruleArgs . funcRule
funcBody :: FuncDecl -> Expr
funcBody = ruleBody . funcRule
funcRHS :: FuncDecl -> [Expr]
funcRHS f | not (isExternal f) = orCase (funcBody f)
| otherwise = []
where
orCase e
| isOr e = concatMap orCase (orExps e)
| isCase e = concatMap orCase (map branchExpr (caseBranches e))
| otherwise = [e]
rnmAllVarsInFunc :: Update FuncDecl VarIndex
rnmAllVarsInFunc = updFunc id id id id . rnmAllVarsInRule
updQNamesInFunc :: Update FuncDecl QName
updQNamesInFunc f = updFunc f id id (updQNamesInTypeExpr f) (updQNamesInRule f)
updFuncArgs :: Update FuncDecl [VarIndex]
updFuncArgs = updFuncRule . updRuleArgs
updFuncBody :: Update FuncDecl Expr
updFuncBody = updFuncRule . updRuleBody
trRule :: ([VarIndex] -> Expr -> a) -> (String -> a) -> Rule -> a
trRule rule _ (Rule args e) = rule args e
trRule _ ext (External s) = ext s
ruleArgs :: Rule -> [VarIndex]
ruleArgs = trRule (\args _ -> args) undefined
ruleBody :: Rule -> Expr
ruleBody = trRule (\_ e -> e) undefined
ruleExtDecl :: Rule -> String
ruleExtDecl = trRule undefined id
isRuleExternal :: Rule -> Bool
isRuleExternal = trRule (\_ _ -> False) (\_ -> True)
updRule :: ([VarIndex] -> [VarIndex]) ->
(Expr -> Expr) ->
(String -> String) -> Rule -> Rule
updRule fa fe fs = trRule rule ext
where
rule args e = Rule (fa args) (fe e)
ext s = External (fs s)
updRuleArgs :: Update Rule [VarIndex]
updRuleArgs f = updRule f id id
updRuleBody :: Update Rule Expr
updRuleBody f = updRule id f id
updRuleExtDecl :: Update Rule String
updRuleExtDecl f = updRule id id f
allVarsInRule :: Rule -> [VarIndex]
allVarsInRule = trRule (\args body -> args ++ allVars body) (\_ -> [])
rnmAllVarsInRule :: Update Rule VarIndex
rnmAllVarsInRule f = updRule (map f) (rnmAllVars f) id
updQNamesInRule :: Update Rule QName
updQNamesInRule = updRuleBody . updQNames
trCombType :: a -> (Int -> a) -> a -> (Int -> a) -> CombType -> a
trCombType fc _ _ _ FuncCall = fc
trCombType _ fpc _ _ (FuncPartCall n) = fpc n
trCombType _ _ cc _ ConsCall = cc
trCombType _ _ _ cpc (ConsPartCall n) = cpc n
isCombTypeFuncCall :: CombType -> Bool
isCombTypeFuncCall = trCombType True (\_ -> False) False (\_ -> False)
isCombTypeFuncPartCall :: CombType -> Bool
isCombTypeFuncPartCall = trCombType False (\_ -> True) False (\_ -> False)
isCombTypeConsCall :: CombType -> Bool
isCombTypeConsCall = trCombType False (\_ -> False) True (\_ -> False)
isCombTypeConsPartCall :: CombType -> Bool
isCombTypeConsPartCall = trCombType False (\_ -> False) False (\_ -> True)
varNr :: Expr -> VarIndex
varNr (Var n) = n
varNr _ = error "Curry.FlatCurry.Goodies.varNr: no variable"
literal :: Expr -> Literal
literal (Lit l) = l
literal _ = error "Curry.FlatCurry.Goodies.literal: no literal"
combType :: Expr -> CombType
combType (Comb ct _ _) = ct
combType _ = error $ "Curry.FlatCurry.Goodies.combType: " ++
"no combined expression"
combName :: Expr -> QName
combName (Comb _ name _) = name
combName _ = error $ "Curry.FlatCurry.Goodies.combName: " ++
"no combined expression"
combArgs :: Expr -> [Expr]
combArgs (Comb _ _ args) = args
combArgs _ = error $ "Curry.FlatCurry.Goodies.combArgs: " ++
"no combined expression"
missingCombArgs :: Expr -> Int
missingCombArgs = missingArgs . combType
where
missingArgs :: CombType -> Int
missingArgs = trCombType 0 id 0 id
letBinds :: Expr -> [(VarIndex,Expr)]
letBinds (Let vs _) = vs
letBinds _ = error $ "Curry.FlatCurry.Goodies.letBinds: " ++
"no let expression"
letBody :: Expr -> Expr
letBody (Let _ e) = e
letBody _ = error $ "Curry.FlatCurry.Goodies.letBody: " ++
"no let expression"
freeVars :: Expr -> [VarIndex]
freeVars (Free vs _) = vs
freeVars _ = error $ "Curry.FlatCurry.Goodies.freeVars: " ++
"no declaration of free variables"
freeExpr :: Expr -> Expr
freeExpr (Free _ e) = e
freeExpr _ = error $ "Curry.FlatCurry.Goodies.freeExpr: " ++
"no declaration of free variables"
orExps :: Expr -> [Expr]
orExps (Or e1 e2) = [e1,e2]
orExps _ = error $ "Curry.FlatCurry.Goodies.orExps: " ++
"no or expression"
caseType :: Expr -> CaseType
caseType (Case ct _ _) = ct
caseType _ = error $ "Curry.FlatCurry.Goodies.caseType: " ++
"no case expression"
caseExpr :: Expr -> Expr
caseExpr (Case _ e _) = e
caseExpr _ = error $ "Curry.FlatCurry.Goodies.caseExpr: " ++
"no case expression"
caseBranches :: Expr -> [BranchExpr]
caseBranches (Case _ _ bs) = bs
caseBranches _ = error
"Curry.FlatCurry.Goodies.caseBranches: no case expression"
isVar :: Expr -> Bool
isVar e = case e of
Var _ -> True
_ -> False
isLit :: Expr -> Bool
isLit e = case e of
Lit _ -> True
_ -> False
isComb :: Expr -> Bool
isComb e = case e of
Comb _ _ _ -> True
_ -> False
isLet :: Expr -> Bool
isLet e = case e of
Let _ _ -> True
_ -> False
isFree :: Expr -> Bool
isFree e = case e of
Free _ _ -> True
_ -> False
isOr :: Expr -> Bool
isOr e = case e of
Or _ _ -> True
_ -> False
isCase :: Expr -> Bool
isCase e = case e of
Case _ _ _ -> True
_ -> False
trExpr :: (VarIndex -> a)
-> (Literal -> a)
-> (CombType -> QName -> [a] -> a)
-> ([(VarIndex, a)] -> a -> a)
-> ([VarIndex] -> a -> a)
-> (a -> a -> a)
-> (CaseType -> a -> [b] -> a)
-> (Pattern -> a -> b)
-> (a -> TypeExpr -> a)
-> Expr
-> a
trExpr var lit comb lt fr oR cas branch typed expr = case expr of
Var n -> var n
Lit l -> lit l
Comb ct name args -> comb ct name (map f args)
Let bs e -> lt (map (\(v, x) -> (v, f x)) bs) (f e)
Free vs e -> fr vs (f e)
Or e1 e2 -> oR (f e1) (f e2)
Case ct e bs -> cas ct (f e) (map (\ (Branch p e') -> branch p (f e')) bs)
Typed e ty -> typed (f e) ty
where
f = trExpr var lit comb lt fr oR cas branch typed
updVars :: (VarIndex -> Expr) -> Expr -> Expr
updVars var = trExpr var Lit Comb Let Free Or Case Branch Typed
updLiterals :: (Literal -> Expr) -> Expr -> Expr
updLiterals lit = trExpr Var lit Comb Let Free Or Case Branch Typed
updCombs :: (CombType -> QName -> [Expr] -> Expr) -> Expr -> Expr
updCombs comb = trExpr Var Lit comb Let Free Or Case Branch Typed
updLets :: ([(VarIndex,Expr)] -> Expr -> Expr) -> Expr -> Expr
updLets lt = trExpr Var Lit Comb lt Free Or Case Branch Typed
updFrees :: ([VarIndex] -> Expr -> Expr) -> Expr -> Expr
updFrees fr = trExpr Var Lit Comb Let fr Or Case Branch Typed
updOrs :: (Expr -> Expr -> Expr) -> Expr -> Expr
updOrs oR = trExpr Var Lit Comb Let Free oR Case Branch Typed
updCases :: (CaseType -> Expr -> [BranchExpr] -> Expr) -> Expr -> Expr
updCases cas = trExpr Var Lit Comb Let Free Or cas Branch Typed
updBranches :: (Pattern -> Expr -> BranchExpr) -> Expr -> Expr
updBranches branch = trExpr Var Lit Comb Let Free Or Case branch Typed
updTypeds :: (Expr -> TypeExpr -> Expr) -> Expr -> Expr
updTypeds = trExpr Var Lit Comb Let Free Or Case Branch
isFuncCall :: Expr -> Bool
isFuncCall e = isComb e && isCombTypeFuncCall (combType e)
isFuncPartCall :: Expr -> Bool
isFuncPartCall e = isComb e && isCombTypeFuncPartCall (combType e)
isConsCall :: Expr -> Bool
isConsCall e = isComb e && isCombTypeConsCall (combType e)
isConsPartCall :: Expr -> Bool
isConsPartCall e = isComb e && isCombTypeConsPartCall (combType e)
isGround :: Expr -> Bool
isGround e
= case e of
Comb ConsCall _ args -> all isGround args
_ -> isLit e
allVars :: Expr -> [VarIndex]
allVars e = trExpr (:) (const id) comb lt fr (.) cas branch const e []
where
comb _ _ = foldr (.) id
lt bs e' = e' . foldr (.) id (map (\ (n,ns) -> (n:) . ns) bs)
fr vs e' = (vs++) . e'
cas _ e' bs = e' . foldr (.) id bs
branch pat e' = ((args pat)++) . e'
args pat | isConsPattern pat = patArgs pat
| otherwise = []
rnmAllVars :: Update Expr VarIndex
rnmAllVars f = trExpr (Var . f) Lit Comb lt (Free . map f) Or Case branch Typed
where
lt = Let . map (\ (n,e) -> (f n,e))
branch = Branch . updPatArgs (map f)
updQNames :: Update Expr QName
updQNames f = trExpr Var Lit comb Let Free Or Case (Branch . updPatCons f) Typed
where
comb ct name args = Comb ct (f name) args
trBranch :: (Pattern -> Expr -> a) -> BranchExpr -> a
trBranch branch (Branch pat e) = branch pat e
branchPattern :: BranchExpr -> Pattern
branchPattern = trBranch (\pat _ -> pat)
branchExpr :: BranchExpr -> Expr
branchExpr = trBranch (\_ e -> e)
updBranch :: (Pattern -> Pattern) -> (Expr -> Expr) -> BranchExpr -> BranchExpr
updBranch fp fe = trBranch branch
where
branch pat e = Branch (fp pat) (fe e)
updBranchPattern :: Update BranchExpr Pattern
updBranchPattern f = updBranch f id
updBranchExpr :: Update BranchExpr Expr
updBranchExpr = updBranch id
trPattern :: (QName -> [VarIndex] -> a) -> (Literal -> a) -> Pattern -> a
trPattern pattern _ (Pattern name args) = pattern name args
trPattern _ lpattern (LPattern l) = lpattern l
patCons :: Pattern -> QName
patCons = trPattern (\name _ -> name) undefined
patArgs :: Pattern -> [VarIndex]
patArgs = trPattern (\_ args -> args) undefined
patLiteral :: Pattern -> Literal
patLiteral = trPattern undefined id
isConsPattern :: Pattern -> Bool
isConsPattern = trPattern (\_ _ -> True) (\_ -> False)
updPattern :: (QName -> QName) ->
([VarIndex] -> [VarIndex]) ->
(Literal -> Literal) -> Pattern -> Pattern
updPattern fn fa fl = trPattern pattern lpattern
where
pattern name args = Pattern (fn name) (fa args)
lpattern l = LPattern (fl l)
updPatCons :: (QName -> QName) -> Pattern -> Pattern
updPatCons f = updPattern f id id
updPatArgs :: ([VarIndex] -> [VarIndex]) -> Pattern -> Pattern
updPatArgs f = updPattern id f id
updPatLiteral :: (Literal -> Literal) -> Pattern -> Pattern
updPatLiteral f = updPattern id id f
patExpr :: Pattern -> Expr
patExpr = trPattern (\ name -> Comb ConsCall name . map Var) Lit
isPublic :: Visibility -> Bool
isPublic = (== Public)