Design a type system for a hobby/toy programming language.
Asked in the screening_coding stage. Screening coding round.
Implement infer_type(expr), which returns the inferred type of a valid abstract syntax tree, or "TypeError" when type checking fails.
Expressions use dictionaries: {"var": "x"}, {"let": {"name": "x", "value": expr, "body": expr}}, {"lambda": {"param": "x", "type": "Int", "body": expr}}, and {"call": {"function": expr, "argument": expr}}. Integers and booleans are literals. Operators are represented as {"op": "+", "left": expr, "right": expr}. Supported operators are +, -, *, <, and ==. if uses {"if": {"condition": expr, "then": expr, "else": expr}}.
Return "Int", "Bool", or function types such as "(Int)->Bool".
def infer_type(expr):