4

I'm writing a symbolic execution engine for Haskell using GHC, and often I need to find the instance implementations of various functions in the program. However, after leafing through many ASTs produced by the typechecker, I can't see any way to tie a function call to its implementation in an instance block. The AST doesn't have the information to support the obvious solution of matching the Unique keys. Unlike top-level function definitions, none of the Uniques in the instance function binding match the Unique of the callsite. For example, in this simple program:

module M where
  class A a where
    foo :: a b -> b

  newtype Box a = Box a
  instance A Box where
    foo (Box a) = a

  bar = foo (Box ())

in the body of bar, foo has unique id rrZ. Within the HsBind of the instance definition, there are the following varName-varUnique pairs:

  • In top-level AbsBind:
    • $cfoo: a1dd
    • foo: a1de
  • In nested AbsBind
    • foo: a1dg

Since none of them match the callsite, I've resorted to an indirect method of matching the type at the callsite against all the types that have the same name, but this requires me to write separate logic for instances from top-level functions. Is there a unified way to find the implementation of some function?

concat
  • 3,107
  • 16
  • 30
  • It dawned on me recently that the `Unique`s can't match because the instance isn't unique in general. While it's obvious in the example I provided, for `bar = foo` it wouldn't, because the constraint `A a =>` on `bar` is only solved later whenever `bar` is fully parameterized. – concat Nov 04 '19 at 07:00

0 Answers0