
A concern, to be sure. On the flip side, it might be better to know what
you are actually exposing (also meaning fewer things would constitute a
breaking change).
On Apr 13, 2014 5:00 PM, "John Lato"
It's possible to restrict LogTree.Internal to be visible only within the package (see cabal's other-modules field), but please don't do so. You will inevitably fail at providing every necessary function or accommodating all reasonable uses of your library. Then some user will either write their own, use something else or, if you're lucky, fork your library and send you a merge request. It will happen (unless you have no other users).
As a recent example, I was using a library that had an internal data structure, 'A' (completely unexposed) as part of an exposed data structure 'B'. Both had 'deriving Generic' clauses. However, the Generic instance of 'B' was mostly useless because if you wanted to use the Generic instance to declare e.g. 'instance Binary B', it's also necessary to create a Binary instance for 'A'. Which was impossible for users, because 'A' was completely unexposed. When I pointed this out, the library's author graciously accepted a patch to expose the type constructor 'A' (I'm not entirely happy with this solution either, but for now we can't think of anything better).
You could take this as an implementation flaw of Generic as it's currently implemented (which it possibly is), however I would hope you also take it as a demonstration of how data abstraction can interact with many different language features in often-subtle ways. I think erring on the side of allowing users maximum freedom is the best choice for now (preferably stashed in modules/functions with names like 'internal' or 'unsafe').
John
On Sun, Apr 13, 2014 at 7:02 AM, Luke Clifton
wrote: Hi David,
I think you can do something like providing a LogTree.Internal module which you use internally and which exports everything you need, and making your LogTree module which re-exports only the safe subset which "unknown" code would then import. I don't think there is a way of stopping anyone from importing your LogTree.Internal module though.
On Sun, Apr 13, 2014 at 9:42 PM, David Banas
wrote: Hi all,
I've defined a typeclass, *LogTree*, and would like to put each instance definition in its own source file, in order that *LogTree.hs *not grow to a ridiculous length. I'm attempting to use data abstraction, in order to future-proof the user interface to this class. So, for instance, I don't make all of the data constructors defined in LogTree accessible, via the module export list, but rather force the user to use certain "helper" functions, instead. However, the individual instance definitions *do* need access to these data constructors, but they're in a different source file.
*Is this possible? That is, is it possible to provide different export lists to "friendly" vs. "unknown" client code?*
Thanks, -db
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe