1. Do we support `foo :: TypeError (Text "") -> TypeError (Text ""); foo = id`? I don't have a strong feeling one way or the other, but it would be nice to have this specified. *Lennart*: I would expect this to result in a type error at some point. If, after typechecking, there are any residual `TypeError` occurrences in types then something has gone wrong.
#### Iavor's Answers to RAE's Questions
I think of `TypeErrror` as a rather special type function, which only makes sense in two places in the syntax of the language:
1. as the only constraint in the context of an instance declaration, and
1. as the right-hand side of a type family instance.
The idea is that whenever a type function is about to reduce to `TypeError`, we stop the evaluation and record a custom type error to be reported by GHC. It doesn't matter if the function evaluation was in the context of a given or wanted constraint. Similarly, if an instance ever reduces to `TypeError`, then we also report a custom type error.
With this in mind the answers to your questions would be:
1.`TypeError` should not appear directly in a given context.
1. As mentioned above, the methods of an instance with `TypeError` in the context are irrelevant. I think it is OK to simply leave them unspecified, or define them as `undefined`.
1.`TypeError` should not appear in types written by the user, except for the two special cases above. So no `TypeError` in user-defined type signatures, type declarations, class instance heads, parameters to type functions, etc.
The current implementation does not have any explicit checks to make sure that programmers don't write `TypeError` in places where they are not supposed to. It might be nice to implement such a check, but I am not sure it is really necessary. With the current implementation, if you wrote `TypeError` in a place that you were not supposed to, you would get the same behavior as for any other type function with no instances.