
Christiaan Baaij:
I believe that you are asking about type functions. Specifically, I think what you are asking is this:
How can I normalise a type, by rewriting it exhaustively using the top-level type-function definitions
That is indeed a better formulation of my original question
I think the function TcTyFuns.tcNormaliseFamInst (rather an odd name!) does this. But it's not very helpful to you because it's in the main typechecker monad.
At the moment it is not such a big problem that it is in the typechecker monad, as we run some parts of our compiler in a GHC Monad, and can thus initialize a typechecker monad with the function TcRnMonad.initTc.
However, at the moment I can't get to normalise the types as far as I had hoped. Here is an example of my debug output:
Before normalisation: Types.Data.Num.Decimal.Literals.D4 Types.Data.Num.Ops.:*: Types.Data.Num.Decimal.Literals.D3
After normalisation: Types.Data.Num.Decimal.Digits.Dec (Types.Data.Num.Decimal.Digits.DecN Types.Data.Num.Ops.:. Types.Data.Num.Decimal.Digits.Dec4) Types.Data.Num.Ops.:*: Types.Data.Num.Decimal.Digits.Dec (Types.Data.Num.Decimal.Digits.DecN Types.Data.Num.Ops.:. Types.Data.Num.Decimal.Digits.Dec3)
So, currently I can normalize the synonyms D4 and D3, but I can't normalize the type function :*:. Maybe it has something to do with how I load the module and its dependencies.
Yes, it has something to do with module loading and the type-checker monad. It's not enough to load the modules, you also need to initialise those components of the type-checker monad that contain the environment of visible type instance declarations. The component is called tcg_fam_inst_env and you can see in the function TcRnDriver.tcRnImports how to extend it. You did well in remembering to load the orphan modules, but you also ought to call FamInst.checkFamInstConsistency to check for overlapping instances in the modules that you are loading (it's used right at the end of TcRnDriver.tcRnImports). Hope that helps a bit. Manuel