haskell - Determining if an Exp 'e' isClosed based on free variables? -


i'm not sure start or how write isclosed function below. appreciated! below have far.

isclosed supposed take in value e of type exp , determine if it's closed or not evaluating below:

-- identifiers % expressions , variables type id = string  -- "builtin" functions. data op = succ | pred | ifzero            deriving (show, ord, eq)  -- expressions of l data exp = var id          | nat integer          | op op          | lam id exp          | app exp exp            deriving (ord, eq, show)  -- isclosed e true if , if there no free variables in e -- "free" means variable not declared surrounding %.        -- example, in expression  -- x (%x. x (%y.xz)) (%y.x)  -- there 5 occurrences of x.  first "free".  second -- parameter % expression , never substituted for. -- third , fourth occurrences refer parameter of -- enclosing % expression.  fifth free.  -- examples: (%x. %y. x y) closed; (%x. y %y. x y) not since -- first occurrence of y free.  isclosed :: exp -> bool isclosed lam{} = true isclosed _ = false 

how like:

isclosed :: exp -> bool isclosed exp = go [] exp   go bindings (var id)     = id `elem` bindings   go _        (nat _)      = true   go _        (op _)       = true   go bindings (lam id exp) = go (id:bindings) exp   go bindings (app fn arg) = go bindings fn && go bindings arg 

let's give test ride:

*main> isclosed (var "e") false *main> isclosed (lam "e" (var "e")) true *main> isclosed (lam "e" (var "x")) false *main> isclosed (app (lam "e" (var "x")) (nat 3)) false *main> isclosed (app (lam "e" (var "e")) (nat 3)) true 

alternatively, can first write freevars helper , implement isclosed via that:

isclosed :: exp -> bool isclosed = null . freevars  freevars :: exp -> [id] freevars exp = go [] exp   go bindings (var id)     | id `elem` bindings   = []     | otherwise            = [id]   go _        (nat _)      = []   go _        (op _)       = []   go bindings (lam id exp) = go (id:bindings) exp   go bindings (app fn arg) = go bindings fn ++ go bindings arg 

and then

*main> freevars (var "e") ["e"] *main> freevars (lam "e" (var "x")) ["x"] *main> freevars (lam "e" (var "e")) [] *main> freevars (app (lam "e" (var "x")) (nat 3)) ["x"] *main> freevars (app (lam "e" (var "e")) (nat 3)) [] 

Comments

Popular posts from this blog

1111. appearing after print sequence - php -

java - WARN : org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/board/] in DispatcherServlet with name 'appServlet' -

Ruby on Rails, ActiveRecord, Postgres, UTF-8 and ASCII-8BIT encodings -