The type check function in Fig. 5.2 tries to guess the correct type when
there is a type error. In some cases, the guess is arbitrarily chosen to be int, which
may lead to spurious type errors later on. A way around this is to have an extra
type: unknown, which is only used during type checking. If there is a type error
and there is no basis for guessing a correct type, unknown is returned (the error is
still reported, though). If an argument to an operator is of type unknown, the type
checker should not report this as a type error but continue as if the type is correct.
The use of an unknown argument to an operator may make the result unknown as
well, so these can be propagated arbitrarily far.
Change Fig. 5.2 to use the unknown type as described above.