[Haskell-cafe] Trouble splitting up source into multiple files, when using data abstraction.

John Lato jwlato at gmail.com
Mon Apr 14 00:00:07 UTC 2014

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').


On Sun, Apr 13, 2014 at 7:02 AM, Luke Clifton <ltclifton at gmail.com> 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 <capn.freako at gmail.com>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 at haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20140413/03863e29/attachment.html>

More information about the Haskell-Cafe mailing list