
Hi Csaba, Thanks for your answer. I think I'm doing something very similar to you. I'm converting the GHC AST to my own AST with this code: https://gist.github.com/chrisdone/96e228f12bdbc3c43d06718467e69029#file-main... I have an Id type that's similar to yours, data Id = Id { idStableName :: {-# UNPACK #-}!ByteString , idUnique :: {-# UNPACK #-}!Unique , idCategory :: !Cat } deriving (Generic, Data, Typeable, Eq, Show, Ord) And (I think) I've solved my first question by adding that category field, which can be one of: data Cat = ValCat | DataCat | ClassCat deriving (Generic, Data, Typeable, Eq, Show, Ord) When an expression like this comes along: AppE (AppE (VarE (Id { idStableName = "main:Main.C:Wiggle" , idUnique = Unique 8214565720323785205 , idCategory = ClassCat })) (TypE (Typ "Int"))) (VarE (Id { idStableName = "main:Main.$cfoo" , idUnique = Unique 6989586621679010971 , idCategory = ValCat })) VarE (Id { idStableName = "main:Main.$cbar" , idUnique = Unique 6989586621679010975 , idCategory = ValCat }) It constructs a class dictionary for the class "Wiggle", with the methods "foo" and "bar", and the interpreter treats Wiggle as a regular data constructor. Meanwhile, when an nth class method (like "main:Main.$cfoo") is resolved, it produces a Method, and when applying a method to a data constructor Wiggle, the interpreter access the nth slot. That works out. An example is here: https://gist.github.com/chrisdone/771292425a9f1bb428ef4eda3779dc40 See how the "main:Main.$fWiggleInt" is resolved to the above dictionary. As for the second question, and your answer, I am a bit puzzled, maybe you can clarify?
Regarding the names you can use qualified (module + occ) names for exported ids. (see: Var.isExportedId).
For non exported Id's you can rely on unique values.
You say that for exported names I can rely soley on the stable name (package+module+ident), and for internal IDs I can use the Unique? I believe that's what I'm reproducing, here. The following name isn't resolved: Id { idStableName = "base:GHC.Base.$fApplicativeIO" , idUnique = Unique 8214565720323784738 , idCategory = ValCat } If I list all bindings available, I find this name, which has a different Unique: Id { idStableName = "base:GHC.Base.$fApplicativeIO" , idUnique = Unique 8214565720323793553 <--- differing , idCategory = ValCat } So if I were to apply your approach and do exported lookups by idStableName, and local-module lookups (beta substitution) by Unique, it should work out. The question is whether "base:GHC.Base.$fApplicativeIO" is actually exported -- I presume all instance dictionaries are exported. I will give it a try and report back to you! Cheers!