たぶん解決

のつづき

中を調べるには単純な例に限る。

# \x->x x
print "expr1_3"
expr1_3 = Lambda(["x"], Apply(Ref("x"), [Ref("x")]))
print_type(expr1_3)

これを実行すると、

expr1_3
([([([([...]) -> <variable type>]) -> <variable type>]) -> <variable type>]) -> <variable type>

自己再帰してたっぽい。つまりこういう感じ、

type = TFunc()
type.params_t = [type]
type.ret_t = TVar()

ということで、Lambdaの型では、引数に循環参照が無いよう検知すればいいだけだった。id idを許すためには、Applyではチェックしない。

チェックのあるなしにかかわらず、やっぱりid idがどうしても循環参照する。単なるマッピングではなく、varの同値関係を優先扱いする必要があるっぽい。