Debugging partial functions by the rules

Claus Reinke claus.reinke at
Wed Nov 15 11:52:02 EST 2006

> Sounds useful to me (though one might occasionally want to have
> access to just the current location, without context - suggesting 
> perhaps a list/stack of strings rather than a pre-concatenated string).

actually, there's a bit about your proposal (on the wiki page) that I don't 
quite follow, namely whether the annotated function versions are hand-written 
(needed only for making explicit use of the annotation parameter) or 
generated (convenient for passing on the annotation parameter). here are 
the use cases I can see arising:

case 1: I want to have explicit access to the call site location info

    - I write both head and headError, and the pragma
    - calls to head will be translated into calls to headError <srcLoc>,
        where I can process that information however I need to.

    {-# SRC_LOC_ANNOTATE head #-}
    head (h:_) = h

    headError srcLoc (h:_) = h
    headError srcLoc _ = error ("head of empty list: "++show srcLoc)

case 2: I have a function that calls annotated functions

    2a: I want to have explicit access to the location info

    - I write both the function and its variant, and the pragma
    - calls to the function will be translated into annotated calls 
        to its variant, I have to handle the information myself

    2b: I just want to build up call stack information

    - I write only the function, and its pragma
    - a variant is generated, affecting calls to annotated functions
        as described on the web page

case 0: I have a function with non-exhaustive left-hand sides, 
            and I want the default branch to refer to the call site

    - I write only head, and its pragma
    - a definition of headError is generated, differing from head
        only in the extra parameter, and in the error branch which
        refers to that parameter (see case 1 for code)
    - calls to head will be translated into calls to headError <srcLoc>.

    {-# SRC_LOC_ANNOTATE head #-}
    head (h:_) = h

[instead of generating variants as separate functions, one might 
 simply transform the originals; the default branch should also be
 augmented in 2b, as in 0]

cases 1&2 are as on the wiki page, where I think 2b is suggested,
as a convenient default. case 2a would arise naturally if we annotate 
a function that also happens to call other annotated functions. and
case 0 is the one that started this discussion, so it would be nice not
to have to write out the boilerplate variants by hand.

does this make sense?

More information about the Glasgow-haskell-users mailing list