I am making a pure, recursive, transformation over an AST type and noticed that in some cases there is an infinite loop (or at the very least the applications hangs), which is weird because every case arm makes progress. What is REALLY weird is that manually eliminating a shared expression with a let binding resolves the issue.
SSCCE
eraseTypesExpr : Expr -> Expr
eraseTypesExpr expr = case expr of
-- some other cases
EApp f a -> case eraseTypesExpr a of
EVar x -> if H.isTyBinderId x then (eraseTypesExpr f) else EApp (eraseTypesExpr f) (eraseTypesExpr a)
EType _ -> eraseTypesExpr f
_ -> EApp (eraseTypesExpr f) (eraseTypeExpr a)
Eliminating two occs of eraseTypeExpr a results in a perfectly responsive application:
eraseTypesExpr : Expr -> Expr
eraseTypesExpr expr = case expr of
-- some other cases
EApp f a ->
let ea = eraseTypesExpr a
in case ea of
EVar x -> if H.isTyBinderId x then (eraseTypesExpr f) else EApp (eraseTypesExpr f) (eraseTypesExpr a)
EType _ -> eraseTypesExpr f
_ -> EApp (eraseTypesExpr f) ea
Quick Summary: ???
I am making a pure, recursive, transformation over an AST type and noticed that in some cases there is an infinite loop (or at the very least the applications hangs), which is weird because every case arm makes progress. What is REALLY weird is that manually eliminating a shared expression with a let binding resolves the issue.
SSCCE
Eliminating two occs of
eraseTypeExpr a
results in a perfectly responsive application: