# Type class instances in scope

Edward Z. Yang ezyang at mit.edu
Wed May 24 12:51:50 UTC 2017

```Hi Tom,

Here is what I was thinking when I made the suggestion:

1. Determine the transitive set of 'Module' that you need to load

So, there are a few problems with your code below:

- For external packages, it's sufficient to use 'loadInterface'
to load a module, since this will suck the module's interface
(and instances) into the EPS.

- But you are not looking at the EPS.  You need to use something
like tcGetInstEnvs (that is in the wrong monad; but you can
still look at this code) to get instances from the EPS.

- But to run 'loadInterface', you need a 'Module', not a
'ModuleName' as in your code below.  You should read off the 'Module'
from the dependencies and usages of the module interface:
look at 'ModIface'.

- By looking at only imports of your local modules, you will only
get the immediate set of imports, not the transitive closure.
So you need to recursively do this for each 'ModIface' you load.

Edward

Excerpts from Tom Sydney Kerckhove's message of 2017-05-22 05:20:37 +0200:
> Hi Edward,
>
> I'm sorry to have to bother you with this again, but I seem to be stuck
> with this approach.
> I think I don't really understand what 'load the interfaces' means.
>
> Here's what I tried:
>
> getInstancesFromTcmodule :: GhcMonad m => TypecheckedModule -> m ()
> getInstancesFromTcmodule tmod = do
>     let (tcenv, md) = tm_internals_ tmod
>     let insts = tcg_insts tcenv
>     printO insts
>     printO \$ md_insts md
>     printO \$ tcg_inst_env tcenv
>     graph <- depanal [] True
>     printO graph
>     forM_ graph \$ \mod_ -> do
>         forM_ (ms_textual_imps mod_) \$ \(_, imp) -> do
>             let modname = unLoc imp
>                 (Target
>                  { targetId = TargetModule modname
>                  , targetAllowObjCode = True
>                  , targetContents = Nothing
>                  })
>             getModSummary (unLoc imp) >>= printO
>         tcmod <- parseModule mod_ >>= typecheckModule >>= loadModule
>         let (tcenv', md') = tm_internals_ tcmod
>         printO \$ tcg_insts tcenv'
>         printO \$ md_insts md'
>         printO \$ tcg_inst_env tcenv'
> ```
>
> I just wanted to see if I could find all the relevant instances.
>
> I do find all the instances in the current `TypecheckedModle`, but none
> of the others because at `loadSuccessfully \$ loadUpTo modname`, I get an
> error saying that `Test.QuickCheck a package module`.
> I think that means that it's not locally defined, but rather part of a
> package that I'm using.
> Unfortunately that means that I don't really understand how I can load
> it to find the instances.
>
> Would you please hint me at the next step?
>
> Thank you for your time.
>
> On 19-05-17 23:00:41, Tom Sydney Kerckhove wrote:
> > On 19-05-17 08:35:32, Edward Z. Yang wrote:
> > > Excerpts from Tom Sydney Kerckhove's message of 2017-05-19 11:05:17 +0200:
> > > > > But if you
> > > > > really need all instances, you will have to first arrange to load
> > > > > the interfaces of ALL modules transitively imported by your module.
> > > >
> > > > I don't really mind the time it takes to do this, but that's annoying to
> > > > write.
> > > >
> > > > Thank you for your help! I will look into it.
> > >
> > > Another possibility is, if you can programatically list the types that
> > > you are interested in, you can load all of those, and then the instances
> > > for those types will be ready.
> >
> > That's probably the most feasible approach.
> > Then I'd have to find all the types in scope, and find their interfaces.
> >
> > I know how to get all the TyThing's in scope, so it should be easy-ish
> > to get started.
> >
> > Thanks!
> >
> > --
> > Tom Sydney Kerckhove
>
```