[Template-haskell] How to extract name and type of exported functions in modules

Simon Peyton-Jones simonpj at microsoft.com
Tue Oct 20 10:38:33 EDT 2009

[ccing ghc-users]

| I'm trying to extract the names and types of exported functions in a module.

Quite a reasonable request.  But it's not conveniently possible at the moment.  Here's what you can do in the Q monad:

class (Monad m, Functor m) => Quasi m where
	-- Fresh names
  qNewName :: String -> m Name

	-- Error reporting and recovery
  qReport  :: Bool -> String -> m ()	-- Report an error (True) or warning (False)
					-- ...but carry on; use 'fail' to stop
  qRecover :: m a -> m a -> m a		-- Recover from the monadic 'fail'
					-- The first arg is the error handler
	-- Inspect the type-checker's environment
  qReify :: Name -> m Info
  qLocation :: m Loc

	-- Input/output (dangerous)
  qRunIO :: IO a -> m a

But you want one more function:

  qReifyModule :: String -> m ModuleInfo

where ModuleInfo is something like:

data ModuleInfo = MI { mi_exports :: [Name]
                     , ... instances,rules, etc }

Then you could use qReify to get info about a particular thing.

This would not be hard in principle, the details need thought.  For example, if module exports T( C1, C2), where C1, C2 are constructors of T which also has constructors C3, C4, what should appear in mi_exports?  Should mi_exports reflect the structure of the export list (see the AvailInfo type in GHC).

What is the info for an instance?
Do we need a way to ask for all the instances of a class (or rules for a function) regardless of what module those instances come from?   etc

Does this ring bells for anyone else?  Would someone like to write the spec?  Are there other reify-related things that we need?


| -----Original Message-----
| From: template-haskell-bounces at haskell.org [mailto:template-haskell-
| bounces at haskell.org] On Behalf Of Oscar Finnsson
| Sent: 16 October 2009 18:47
| To: template-haskell at haskell.org
| Subject: [Template-haskell] How to extract name and type of exported functions in
| modules
| Hi,
| I'm trying to extract the names and types of exported functions in a module.
| At the moment I've managed to get a list of all functions in a module
| but I can't seem to figure out how to get their types.
| Lets say I got the module
|     module Foo where
|     foo1 :: String -> String
|     foo1 value = value
|     foo2 = "hej"
| and then in anothor module...
|     module Bar where
|     bar = $(getAllFunctions "<some-path>/Foo.hs")
| At the moment I got getAllFunctions returning ["foo1","foo2"], but I
| would really like to get it to return [("foo1",AppT (ConT "String")
| (ConT "String")), ("foo2",ConT "String")]
| Using "parseModuleWithMode" from Language.Haskell.Exts I can get hold
| of the names and the type signature of foo1 (since it's specified in
| the source code) but I cannot get hold of the type signature of foo2
| (since it's not specified in the source code).
| Is there another way to get the names/signatures of exported functions
| from a module other than using parseModuleWithMode so the developer
| writing the Foo-module isn't forced to explicitly supply type
| signatures of the exported functions?
| If I try "reify" to get information about the functions I get the error message:
| "foo1 is not in scope at a reify"
| This seems to be a known bug about reify (reported here
| http://hackage.haskell.org/trac/ghc/ticket/2339). My problem is that I
| cannot use the workaround since I don't know the name of the
| functions.
| Another disadvantage with this approach is that "getAllFunctions" must
| have access to the source code of the module and that I must supply
| the path the the module. If possible I would like to have code such as
|     bar = $(getAllFunctions "Foo")
| instead of "<come-path>/Foo.hs".
| Regards,
| Oscar Finnsson
| _______________________________________________
| template-haskell mailing list
| template-haskell at haskell.org
| http://www.haskell.org/mailman/listinfo/template-haskell

More information about the Glasgow-haskell-users mailing list