Proposal: Make Semigroup as a superclass of Monoid

Reid Barton rwbarton at gmail.com
Mon May 4 18:37:10 UTC 2015


On Mon, May 4, 2015 at 12:58 PM, David Feuer <david.feuer at gmail.com> wrote:

> Wouldn't your concerns about NonEmpty be addressed by keeping its type
> abstract? Then something like Liquid Haskell could be used to define it
> better.
>
There are (at least) two possible designs for a "non-empty list type".

1. A refinement type (as in LiquidHaskell) of [t] whose values include only
the non-empty lists. Call it NonEmptyLiquid t. You can pass a
NonEmptyLiquid t to a function that expects a [t], and you can pass a [t]
to a function that expects a NonEmptyLiquid [t] if the compiler can prove
that your [t] is nonempty. If it can't then you can add a runtime test for
emptiness and in the non-empty case, the compiler will know the list is
non-empty.

2. A new type NonEmptySolid t that is totally unrelated to [t] like you can
define in Haskell today. The advantage is that NonEmptySolid is a
full-fledged type constructor that can have instances, be passed to other
type constructors and so on. The disadvantage is that you need to
explicitly convert in your program (and possibly do a runtime conversion
also) in either direction between [t] and NonEmptySolid t.

I think most people who want a "non-empty list type" want 1, not 2. Option
2 is bad for API design because it forces the users of your library to care
exactly as much as you do about non-emptiness. If you imagine adding other
sorts of lists like infinite lists, fixed-length or bounded-length lists,
lists of even length etc. then it quickly becomes clear that having such an
array of incompatible list types is not the way to go. We just want lists
to be lists, but we also want the compiler to make sure we don't try to
take the head of an empty list.

Those who use a NonEmpty type prefer option 2 over option 0 "type
NonEmptyGas t = [t] -- and just hope"; but that doesn't mean they prefer
option 2 over option 1. Those who really want option 2 can also define it
as a newtype wrapper on option 1, as you noted.

So, to answer your question, no, it wouldn't really make a difference if
the NonEmpty type was abstract. That would just smooth the transition to a
design that I think people don't really want.

Finally, let me reiterate that there seem to be no advantages to moving a
NonEmpty type into base rather than into its own small package. We don't
need base to swallow up every small popular package.

Regards,
Reid Barton
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/libraries/attachments/20150504/40c055d2/attachment.html>


More information about the Libraries mailing list