ExprTyp is not (necessarily) an injective type function. This means that being handed something of type ExprType m doesn't nail down m -- there may also be a different n such that ExprType n = ExprType m. This makes the type of expTypArg a bit tricky: it uses return-type polymorphism in the same way, e.g., read does, so you'll need to give extra type annotations to its result in the same situations you have to do with read.
ExprTyp is not (necessarily) an injective type function. This means that being handed something of type
ExprType m
doesn't nail downm
-- there may also be a differentn
such thatExprType n = ExprType m
. This makes the type ofexpTypArg
a bit tricky: it uses return-type polymorphism in the same way, e.g.,read
does, so you'll need to give extra type annotations to its result in the same situations you have to do withread
.