How to get types including constraints out of TypecheckedModule

Daniel Gröber dxld at
Fri Sep 25 05:40:18 UTC 2015

(whoops, didn't send this to the list)
On Fri, Sep 18, 2015 at 09:22:09AM +0000, Simon Peyton Jones wrote:
> I have not looked in detail, but I'm confident that all the info you
> want is there.   For let/where/top-level bindings, the polymorphic
> binders you want are in the 'AbsBinds' construct.
>   | AbsBinds {                      -- Binds abstraction; TRANSLATION
>         abs_tvs     :: [TyVar],
>         abs_ev_vars :: [EvVar],  -- ^ Includes equality constraints
>        -- | AbsBinds only gets used when idL = idR after renaming,
>        -- but these need to be idL's for the collect... code in HsUtil
>        -- to have the right type
>         abs_exports :: [ABExport idL],
>         -- | Evidence bindings
>         -- Why a list? See TcInstDcls
>         -- Note [Typechecking plan for instance declarations]
>         abs_ev_binds :: [TcEvBinds],
>         -- | Typechecked user bindings
>         abs_binds    :: LHsBinds idL
>     }

Awesome that's exactly what I was looking for. I noticed the
constructor before but it looked like that's just for type
declarations and not for inferred types coming from the typechecker.

> The info you want is in the abs_exports field:
> data ABExport id
>   = ABE { abe_poly  :: id           -- ^ Any INLINE pragmas is attached to
this Id
>         , abe_mono  :: id
>         , abe_wrap  :: HsWrapper    -- ^ See Note [AbsBinds wrappers]
>              -- Shape: (forall abs_tvs. abs_ev_vars => abe_mono) ~ abe_poly
>         , abe_prags :: TcSpecPrags  -- ^ SPECIALISE pragmas

> This pairs the "polymorphic" and "monomorphic" versions of the bound
> Ids.   You'll find the monomorphic one in the bindings in the
> abs_binds field; and you'll find the very same binder in the abe_mono
> field of one of the ABExport records.  Then the corresponding abe_poly
> Id is the polymorphic one, the one with type
>       foo :: forall a. Num a => a

What if I have a binder:

    (foo, bar) = (show, show)

I can now get the polymorphic types of foo and bar respectively but
how do I'm not sure how I'm meant to zip up the monomorphic type of
`pat_rhs_ty`, i.e. the type of the whole rhs, with the polymorphic
types in `abs_exports`.

I mean I could just match up the type variables and pull the
constraints in by hand but it just seems like there already ought to
be a way to do this somewhere?

Alternatively my strategy to do this would be to build a map from
TyVar to the constraint and then going over the monomorphic types and
for each TyVar that's mentioned in the monomorphic type pull in the
relevant constraint and apply those to the monomorphic type. Does that
sound sensible at all? I have no idea how equality constraints and all
that fancy stuff are encoded so I hope that doesn't need any special
handling ;)

> I hope this is of some help.  If so, would you like to update the
> Commentary (on the GHC wiki) to add the information you wish had been
> there in the first place?  Thanks!

Very much so, thanks :)

I'd love to put this in the commentary somewhere but looking at I can't actually find
anywhere this would fit in and it just seems like an awefully specific
thing to put there. Maybe it would be better to improve the comments
instead for the next person that goes looking thoguth the source
trying to figure out where the types end up.

For example the comment on AbsBinds could mention that this is where
the typechecker stores inferred constrainst or something like that.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <>

More information about the ghc-devs mailing list