def eval(expr, env): return match expr: case Atom(x): Success(lookup(env, x)) case List(['quote', x]): Success(x) case List(['if', cond, then, else_]): eval(cond, env).flatmap( lambda v: eval(then if v else else_, env) ) case List([fn, *args]): eval(fn, env).flatmap( lambda f: traverse(args, lambda a: eval(a, env)) .flatmap(lambda vals: apply(f, vals)) )