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

David Thomas davidleothomas at gmail.com
Mon Apr 14 00:30:10 UTC 2014


Fair enough!  Seems still a good practice to get any functionality you're
using into the stable API, but certainly being able to get things done in
the meanwhile is not a bad thing.
On Apr 13, 2014 5:28 PM, "Carter Schonwald" <carter.schonwald at gmail.com>
wrote:

> yup!
>
> its accepted convention by the community that *.Internal Modules are not
> subject to ANY API stability guarantees (kinda like the GHC apis :) )
>
>
> On Sun, Apr 13, 2014 at 8:25 PM, Ivan Lazar Miljenovic <
> ivan.miljenovic at gmail.com> wrote:
>
>> On 14 April 2014 10:22, David Thomas <davidleothomas at gmail.com> wrote:
>> > 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).
>>
>> There is the convention that "if it's in a .Internal module, then
>> you're on your own: this module doesn't contribute towards breaking
>> changes in the API".
>>
>> >
>> > On Apr 13, 2014 5:00 PM, "John Lato" <jwlato at gmail.com> wrote:
>> >>
>> >> 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 <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
>> >>>
>> >>
>> >>
>> >> _______________________________________________
>> >> 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
>> >
>>
>>
>>
>> --
>> Ivan Lazar Miljenovic
>> Ivan.Miljenovic at gmail.com
>> http://IvanMiljenovic.wordpress.com
>> _______________________________________________
>> 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/bb14867e/attachment.html>


More information about the Haskell-Cafe mailing list