Proposal: Make Semigroup as a superclass of Monoid

Greg Weber greg at
Tue May 5 15:27:37 UTC 2015

On Mon, May 4, 2015 at 11:37 AM, Reid Barton <rwbarton at> wrote:

> On Mon, May 4, 2015 at 12:58 PM, David Feuer <david.feuer at>
> 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.

I don't think it is bad API design to have the data types explain the
properties of the input. Quite the opposite. In the case of head/tail the
user *must* care the same about emptiness as the library: that difference
makes it common place to ban usage of those functions.

I agree with Henning that I don't suffer from awkwardness with using
NonEmpty: I just use `toList` on occasion.

The issue you have not raised that I am more concerned with is that
NonEmpty only works for lists.
Michael and I figured out how to extend the concept to any (Mono)Foldable
structure and also to be able to demand lengths of > 1.
I still found that directly using NonEmpty is useful just as directly using
a Haskell list is still useful.

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

I agree that this point should be debated more. That should happen
separately from the refinement vs. NonEmpty debate. If it is a separate
package then there is no debate about refinements to have anyways.

I think it would be good to require a justification for putting anything
into base.

> Regards,
> Reid Barton
> _______________________________________________
> Libraries mailing list
> Libraries at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Libraries mailing list