I've created my own datatypes:
datatype typ = Bool | Int | Arrow of typ*typ;
(* i.e., Arrow(argType, returnType) *)
(* diMLazy expressions *)
datatype expr = TrueExpr
| FalseExpr
| IntExpr of int
| VarExpr of string
| PlusExpr of expr*expr
| LessExpr of expr*expr
| IfExpr of expr*expr*expr
| ApplyExpr of expr*expr
| FunExpr of string*string*typ*typ*expr
Using these, i need to write a function isFV that returns a list of any free variables passed into the function. So far, my code is:
fun isFV (exp:expr) =
let
val bound_list = [];
(*Contains returns true if x:string is within a string list.*)
fun contains (i:string, str_list:string list) =
foldr(fn (x,y) => i = x orelse y) false str_list;
fun anaExp (ex:expr, aggr_list:string list) =
case ex of
TrueExpr => []
| FalseExpr => []
| IntExpr (a) => []
| PlusExpr (a, b) => anaExp(a,aggr_list) @ anaExp(b,aggr_list)
| LessExpr (a, b) => anaExp(a,aggr_list) @ anaExp(b,aggr_list)
| IfExpr (a, b, c) => anaExp(a,aggr_list) @ anaExp(b,aggr_list) @ anaExp(c,aggr_List)
| ApplyExpr (a,b) => anaExp(a,aggr_list) @ anaExp(b,aggr_list)
| FunExpr (a, b, c, d, e) => ??????
| VarExpr (a) = if(contains (a,aggr_List)) then [] else [a]
in
anaExp(exp, bound_list)
end
anaExp is meant to initially take an empty list and recursively call itself until it gets a VarExpr term. It'll then add that to aggr_list.
How do i apply the FuncExpr? I know to use the VarExpr as a string type, but what do i use as a typ type? Currently i have:
| FunExpr (a, b, c, d, e) => anaExp(VarExpr(a),aggr_list) @ anaExp(VarExpr(b),aggr_list)
@ anaExp(c,aggr_list) @ anaExp(d,aggr_list) @ anaExp(e,aggr_list)
But we know that passing a typ into anaExp will cause a type error (c and d).