type signatures in export lists

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 They're not implemented, but they won't be until we decide exactly what they mean - it's not simple. (at least the syntax is obvious: http://hackage.haskell.org/trac/haskell-prime/wiki/PermitSignaturesInExports ) One big question: can their presence have any effect? * on the module doing the exporting (conflict with the presence of in-module type-signature for the same thing; type restriction in-module; monomorphism-restriction-lifting or defaulting-removal of the named thing) * on modules importing this one (can a module re-export something, giving it a more restrictive type-signature?) Case study 1: module Foo1 (Foo(..), foo :: Foo) where data Foo = CFoo foo :: Foo foo = CFoo If we interpret it as an in-module type signature, it will be a problem because there already is one for foo. (unless we should relax the rules for uniqueness of type signatures anyway?) Case study 2: module Foo2 (foo :: Foo) where data Foo = CFoo foo :: Foo foo = CFoo The type doesn't need to be exported. (which is more likely if it's just a type synonym than a new type.) So what scope are the names in the export-list-type-signature drawn from? It would be odd if a type signature couldn't be given because some names weren't exported; but it would be odd if a module-user looking at the interface saw some types that weren't defined anywhere visible. This suggests that wildcards in type signatures could be helpful for this: module Foo3 (foo :: Int -> Foo -> Bool) versus module Foo4 (foo :: Int -> _ -> Bool) Open for discussion. Isaac -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFGdmneHgcxvIWYTTURAlTpAJ425ZL8WPzkAeIxRbgGSOQFCKtrnwCeIG0P aawB6GDwSfiRNM20MErBj8E= =KCKj -----END PGP SIGNATURE-----

Isaac Dupree wrote:
One big question: can their presence have any effect? * on the module doing the exporting (conflict with the presence of in-module type-signature for the same thing; type restriction in-module; monomorphism-restriction-lifting or defaulting-removal of the named thing) * on modules importing this one (can a module re-export something, giving it a more restrictive type-signature?)
Letting an export-list type signature be equivalent to a normal one has the benefit of being simple (to explain and implement). Exporting a function with a less polymorphic type than its in-module type seems a bit awkward: you would have two different functions (one internal and one exported) with the same name. If export-list and normal type signatures would be equivalent, the only benefit of allowing the former (compared to writing it in a comment) would be that the compiler can check it for consistency. Right?
The type doesn't need to be exported. (which is more likely if it's just a type synonym than a new type.) So what scope are the names in the export-list-type-signature drawn from? It would be odd if a type signature couldn't be given because some names weren't exported; but it would be odd if a module-user looking at the interface saw some types that weren't defined anywhere visible.
As a user of the module, I would argue that all types (including synonyms) appearing in the signature of an exported function should be exported as well. Not sure if this needs to be enforced, though. Regards, Arie

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Arie Peterson wrote:
Isaac Dupree wrote:
One big question: can their presence have any effect? * on the module doing the exporting (conflict with the presence of in-module type-signature for the same thing; type restriction in-module; monomorphism-restriction-lifting or defaulting-removal of the named thing) * on modules importing this one (can a module re-export something, giving it a more restrictive type-signature?)
Letting an export-list type signature be equivalent to a normal one has the benefit of being simple (to explain and implement). Exporting a function with a less polymorphic type than its in-module type seems a bit awkward: you would have two different functions (one internal and one exported) with the same name.
Agreed.
If export-list and normal type signatures would be equivalent, the only benefit of allowing the former (compared to writing it in a comment) would be that the compiler can check it for consistency. Right?
Currently, it is not allowed to provide duplicate equivalent type-signatures for something. Neither is it allowed to put top-level type signatures that describe a function you import with the intent of exporting it; even so, you should be able to specify your module's interface however the exported functions are provided. How about this: the presence of an export-list type signature means that you will get a compile error if the type provided is not equivalent to the type the exported object has anyway, defined as: "((exportedObject :: type in export list) :: actual type)" typechecks. (where "actual type" is after all effects of monomorphism restriction, defaulting, etc., have taken effect)
The type doesn't need to be exported. (which is more likely if it's just a type synonym than a new type.) So what scope are the names in the export-list-type-signature drawn from? It would be odd if a type signature couldn't be given because some names weren't exported; but it would be odd if a module-user looking at the interface saw some types that weren't defined anywhere visible.
As a user of the module, I would argue that all types (including synonyms) appearing in the signature of an exported function should be exported as well. Not sure if this needs to be enforced, though.
Probably shouldn't be enforced - compilers could be made to give a warning for such bad behavior though. Luckily, "just outside" a module export list is purely a subset of in the module, so ... wait. module Foo1 where data Foo = CFoo1 module Foo2 where data Foo = CFoo2 module Ambig (Foo2.Foo(), foo) where import Foo1 import Foo2 foo = CFoo2 Not in the presence of ambiguity. Here, to be precise, we have (foo :: Foo2.Foo). Since the export list allows and requires Foo to be qualified when Foo is exported, I think it's fair to require that a type signature for 'foo' in the export list qualifies the Foo type it has with Foo2, even though from the module-user's point of view, there is only one Foo. Isaac -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFGdsi7HgcxvIWYTTURAmqPAJ4lIrpsSK7bJWXYMxj/t6SOQkq+XwCgxtu2 9NHc1sG8qMtB6LmzyAfi9FY= =xlwH -----END PGP SIGNATURE-----
participants (2)
-
Arie Peterson
-
Isaac Dupree