[GHC] #9256: Support automatic derivation of an hs-boot file from an hs file

GHC ghc-devs at haskell.org
Tue Jul 1 10:07:57 UTC 2014


#9256: Support automatic derivation of an hs-boot file from an hs file
-------------------------------------+------------------------------------
        Reporter:  ezyang            |            Owner:  ezyang
            Type:  feature request   |           Status:  new
        Priority:  normal            |        Milestone:
       Component:  Compiler          |          Version:  7.8.2
      Resolution:                    |         Keywords:  backpack
Operating System:  Unknown/Multiple  |     Architecture:  Unknown/Multiple
 Type of failure:  None/Unknown      |       Difficulty:  Unknown
       Test Case:                    |       Blocked By:
        Blocking:                    |  Related Tickets:
-------------------------------------+------------------------------------
Description changed by ezyang:

Old description:

> This is essentially augustss's proposal from ticket #1409:
>
> Replying to [comment:13 augustss]:
> > I would settle for a solution where I annotate those entities in a
> module that would go in the hs-boot file.  So instead of me having to go
> through the trouble of creating an extra file I could just say, e.g.,
> >
> > {{{
> > {-# MODULE_MUTUAL_RECURSION_BREAKER T, foo #-}
> > data T = ...
> > foo :: ...
> > foo = ...
> > }}}
> >
> > The values that have an annotation would have to have a type signature.
>
> This should be eminently doable. Here is a more fleshed out proposal.
>
> First, consider the definition of an hs-boot file in the absence of
> mutual recursion (i.e. no breakers are necessary). In this case, the hi-
> boot file for an hs file is precisely the hi file produced after ordinary
> renaming and typechecking of the module.
>
> As an optimization, we would like to avoid typechecking definitions if an
> explicit type signature is present (if the type signature is absent, we
> have no choice.) There are a few choices here: we can force users to give
> top-level declarations for all exported functions (so unconditionally
> error if something is missing, by filtering out the relevant value
> declarations from the source), or we can go ahead and do full
> typechecking when the signature is missing. (The former is probably the
> simplest.)
>
> Now, how to handle breakers? We need to avoid typechecking them, since
> their recursive dependence means that they would not type check properly.
> So we should also filter out their type signatures. (Furthermore, if we
> are inferring some signatures, we need to make sure that their
> definitions don't rely on any breakers. For this reason, it is probably
> simplest to just require explicit type signatures.)
>
> If the mechanism for specifying breakers is exclusionary (as opposed to
> an inclusionary method of saying what values are in the signature), there
> is an awkward problem of syntax for exporting only an abstract type: the
> logical choices mean the wrong thing (`T(..)` seem to imply the type is
> eliminated entirely, whereas `T` seems to imply that the type should be
> eliminated, but not eh constructors.)
>
> Summary:
>
> 1. Require top-level signatures in hs to hs-boot files(?)
> 2. Exclusionary or inclusionary signature pragma?
> 3. Filter out value declarations and excluded files, then
> rename/typecheck as normal, producing hi-boot file

New description:

 This is essentially augustss's proposal from ticket #1409:

 > I would settle for a solution where I annotate those entities in a
 module that would go in the hs-boot file.  So instead of me having to go
 through the trouble of creating an extra file I could just say, e.g.,
 >
 > {{{
 > {-# MODULE_MUTUAL_RECURSION_BREAKER T, foo #-}
 > data T = ...
 > foo :: ...
 > foo = ...
 > }}}
 >
 > The values that have an annotation would have to have a type signature.

 This should be eminently doable. Here is a more fleshed out proposal.

 First, consider the definition of an hs-boot file in the absence of mutual
 recursion (i.e. no breakers are necessary). In this case, the hi-boot file
 for an hs file is precisely the hi file produced after ordinary renaming
 and typechecking of the module.

 As an optimization, we would like to avoid typechecking definitions if an
 explicit type signature is present (if the type signature is absent, we
 have no choice.) There are a few choices here: we can force users to give
 top-level declarations for all exported functions (so unconditionally
 error if something is missing, by filtering out the relevant value
 declarations from the source), or we can go ahead and do full typechecking
 when the signature is missing. (The former is probably the simplest.)

 Now, how to handle breakers? We need to avoid typechecking them, since
 their recursive dependence means that they would not type check properly.
 So we should also filter out their type signatures. (Furthermore, if we
 are inferring some signatures, we need to make sure that their definitions
 don't rely on any breakers. For this reason, it is probably simplest to
 just require explicit type signatures.)

 If the mechanism for specifying breakers is exclusionary (as opposed to an
 inclusionary method of saying what values are in the signature), there is
 an awkward problem of syntax for exporting only an abstract type: the
 logical choices mean the wrong thing (`T(..)` seem to imply the type is
 eliminated entirely, whereas `T` seems to imply that the type should be
 eliminated, but not eh constructors.)

 Summary:

 1. Require top-level signatures in hs to hs-boot files(?)
 2. Exclusionary or inclusionary signature pragma?
 3. Filter out value declarations and excluded files, then rename/typecheck
 as normal, producing hi-boot file

--

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9256#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list