Toolmaking libraries

From HaskellWiki
Revision as of 18:23, 24 March 2007 by PhilippaCowderoy (talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Basic concept

Writing tools involves duplicating work that gets done over and over, and which is affected by the existence of extensions. So let's define interfaces for libraries that make this easier and build some initial implementations, while letting new Haskell implementations with new extensions provide their own implementations that hopefully make the extensions less painful to deal with.


Different tools need different information about code - for example, haddock doesn't care about terms at all, whereas other tools might want to know about dependencies and yet others might perform abstract interpretations on code. So we should provide different views of a source file, with different modules implementing them.

  1. Apps like Haddock need to see the bindings present in a module and some information about those bindings, but no terms. Some term-relevant analyses could still be usefully provided - so long as they're done on-demand, apps that don't need them won't be restricted by tighter well-formedness constraints.
  2. Other applications could use a desugared 'core' language (and preferably means to find the corresponding source for a given piece of core code). At least two variants would make sense:
    • An untyped core. Producing such a language isn't too hard, though there are arguments to be had as to how to handle type classes.
    • An explicitly typed core. This could be trickier - the Right Thing would appear to be a core sufficiently expressive to handle type-preserving translations from the numerous extensions kicking around. Type classes are again an issue, in that much of the work involved with them is in resolving which instance to use - this can be dealt with, but requires some thought.

Proposed interfaces

A proposal for a "just the names" interface (... where I've not filled in concrete details yet, feel free to add in the obvious):

-- [Item] corresponds to the order the items appear in the source
data Module = Module Identifier [Export] [Item]
data Export = ...
data Item = Comment String |
            Function FuncDec |
            Fixity FixityDec |
            Type TypeDec |
            Class ClassDec |
            Instance InstanceDec |

data FuncDec = FuncDec Identifier (Maybe Type)
data FixityDec = FixDec Fixity Int 
data Fixity = FLeft | FRight | FNon
data TypeDec = TypeDec {name :: Identifier,
                        constructors :: [DataConDec],
                        ...} |
               TypeSynonym ... |
               NewType ...
data ClassDec = ...
data InstanceDec = ...

data Type = ...

-- parse source
readSource :: String -> Module

funcs :: Module -> [FuncDec]
types :: Module -> [TypeDec]
classes :: Module -> [ClassDec]
instances :: Module -> [InstanceDec]

-- clearly I have done some handwaving, as FuncDecs'd need tying to their source for this
inferType :: FuncDec -> Type

-- Any other useful queries want adding?