Proposal: Add NonEmpty constructors to the Prelude

In continuation of Simon Jakobi's proposal for a small incremental change to the Prelude to make it more conducive to partial-function-free programming, https://mail.haskell.org/pipermail/libraries/2016-December/027496.html and after some encouragement from the community on reddit, I propose adding the basic constructors of NonEmpty to the Prelude: nonEmpty, (:|), and the type constructor NonEmpty. In practice, users of NonEmpty will often still need a qualified import of Data.List.NonEmpty. But having the constructors available in the Prelude will make the use of NonEmpty more common, and will make programming without partial functions feel more natural and standard. Note: This proposal is separate from Simon's and should not interfere with the acceptance of Simon's. But it is related in that it attempts to achieve the same goals. Discussion period: Until the end of the discussion period of Simon's proposal. Thanks, Yitz

2016-12-28 20:39 GMT+01:00 Yitzchak Gale
I propose adding the basic constructors of NonEmpty to the Prelude: nonEmpty, (:|), and the type constructor NonEmpty.
+1 I'd still like to point out that all three names are exposed by several other packages, mostly with different types: * nonEmpty: https://www.stackage.org/lts-7.14/hoogle?q=nonEmpty&exact=on * (:|): https://www.stackage.org/lts-7.14/hoogle?q=%3A%7C&exact=on * NonEmpty: https://www.stackage.org/lts-7.14/hoogle?q=NonEmpty&exact=on

What are the types and definitions of
nonEmpty, (:|), and the type constructor NonEmpty.
? Must be something generic, overloaded, given the name... On 28.12.2016 20:39, Yitzchak Gale wrote:
In continuation of Simon Jakobi's proposal for a small incremental change to the Prelude to make it more conducive to partial-function-free programming,
https://mail.haskell.org/pipermail/libraries/2016-December/027496.html
and after some encouragement from the community on reddit, I propose adding the basic constructors of NonEmpty to the Prelude: nonEmpty, (:|), and the type constructor NonEmpty.
In practice, users of NonEmpty will often still need a qualified import of Data.List.NonEmpty. But having the constructors available in the Prelude will make the use of NonEmpty more common, and will make programming without partial functions feel more natural and standard.
Note: This proposal is separate from Simon's and should not interfere with the acceptance of Simon's. But it is related in that it attempts to achieve the same goals.
Discussion period: Until the end of the discussion period of Simon's proposal.
Thanks, Yitz _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- Andreas Abel <>< Du bist der geliebte Mensch. Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden andreas.abel@gu.se http://www2.tcs.ifi.lmu.de/~abel/

2016-12-29 13:48 GMT+01:00 Andreas Abel
What are the types and definitions of
nonEmpty, (:|), and the type constructor NonEmpty.
?
See http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-List-NonEmpty.html

Hi, On 12/29/2016 12:48 PM, Andreas Abel wrote:
What are the types and definitions of
nonEmpty, (:|), and the type constructor NonEmpty.
?
Must be something generic, overloaded, given the name...
Indeed, one would assume so, given the names. But:
What are the types and definitions of
nonEmpty, (:|), and the type constructor NonEmpty.
?
See http://hackage.haskell.org/package/base-4.9.0.0/docs/ Data-List-NonEmpty.html
there is nothing generic at all about these: I am assuming that the idea is that these three definitions will be made available for unqualified use (while all other library functions for programming with non-empty lists would have to be imported explicitly from Data.List.NonEmpty, as currently is the case). But these are really poor names for something this specific being made available unqualified everywhere: there are lots of things that could be called "NonEmpty" or "nonEmpty", and ":|" is a perfectly good combinator name for other purposes. So this addition would do little beside increasing the footprint of the Prelude and causing issues clashes with code that happens to use these names already. To quote Yuras Shumovich from a related thread (Add readMaybe (and possibly readEither) to Prelude): "We should be careful with Prelude." Additionally, as is evidenced by the type signatures of the module NonEmpty, the utility of keeping track of non-empty lists at the type level in a language like Haskell is in general limited (which is not to say that it cannot be very useful sometimes). Even in a language with dependent types the approach (of integrating properties with data types) is not always smooth as it may lead to a proliferation of different related but distinct types which quickly becomes clunky. As far as I am aware, solving this conundrum is still an open research problem. (And nothing new under the sun, either: people familiar with Pascal or Ada will have had similar experiences with a proliferation of integral types of various ranges. In simple cases, very useful to ensure e.g. an array index is not out of bounds, but does not go very far.) Finally, why single out "non-empty" specifically as a property worthy to keep track at the type level in the prelude? Why not lists of finite length as well, for example? That could help ensuring termination. (Just to be clear: I am not proposing this. I am just saying that I can't see how adding variations of existing types with specific properties to the prelude possibly can result in a principled design for a language like Haskell as it currently stands.) /Henrik This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham. This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.

Since "nonEmpty" is a predicate that could apply any kind of collection, not just lists, I am strongly -1 on such a proposal. Similarly, "NonEmpty" misses a "List", it should be called "NonEmptyList". --Andreas On 29.12.2016 15:26, Henrik Nilsson wrote:
Hi,
On 12/29/2016 12:48 PM, Andreas Abel wrote:
What are the types and definitions of
nonEmpty, (:|), and the type constructor NonEmpty.
?
Must be something generic, overloaded, given the name...
Indeed, one would assume so, given the names.
But:
What are the types and definitions of
nonEmpty, (:|), and the type constructor NonEmpty.
?
See http://hackage.haskell.org/package/base-4.9.0.0/docs/ Data-List-NonEmpty.html
there is nothing generic at all about these:
I am assuming that the idea is that these three definitions will be made available for unqualified use (while all other library functions for programming with non-empty lists would have to be imported explicitly from Data.List.NonEmpty, as currently is the case).
But these are really poor names for something this specific being made available unqualified everywhere: there are lots of things that could be called "NonEmpty" or "nonEmpty", and ":|" is a perfectly good combinator name for other purposes.
So this addition would do little beside increasing the footprint of the Prelude and causing issues clashes with code that happens to use these names already.
To quote Yuras Shumovich from a related thread (Add readMaybe (and possibly readEither) to Prelude): "We should be careful with Prelude."
Additionally, as is evidenced by the type signatures of the module NonEmpty, the utility of keeping track of non-empty lists at the type level in a language like Haskell is in general limited (which is not to say that it cannot be very useful sometimes). Even in a language with dependent types the approach (of integrating properties with data types) is not always smooth as it may lead to a proliferation of different related but distinct types which quickly becomes clunky. As far as I am aware, solving this conundrum is still an open research problem.
(And nothing new under the sun, either: people familiar with Pascal or Ada will have had similar experiences with a proliferation of integral types of various ranges. In simple cases, very useful to ensure e.g. an array index is not out of bounds, but does not go very far.)
Finally, why single out "non-empty" specifically as a property worthy to keep track at the type level in the prelude? Why not lists of finite length as well, for example? That could help ensuring termination.
(Just to be clear: I am not proposing this. I am just saying that I can't see how adding variations of existing types with specific properties to the prelude possibly can result in a principled design for a language like Haskell as it currently stands.)
/Henrik
This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham.
This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- Andreas Abel <>< Du bist der geliebte Mensch. Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden andreas.abel@gu.se http://www2.tcs.ifi.lmu.de/~abel/

Regardless of if NonEmpty should have been called NonEmptyList years ago
when it was designed years ago (It was modeled on two existing libraries
that took the NonEmpty name and at least one of those authors was vocally
against the longer name, so we might never have been able to consolidate
the implementation at all) and before it was brought into base, randomly
recoloring the bikeshed at this point basically would just guarantee that
all existing users are left with no migration path.
But your point on how annoyingly common the names are does make me shift to
weakly -1 as to including them as part of an 8.6 migration story. Leaving
them where they are in Data.List.NonEmpty and not exporting sconcat in the
Prelude as an implementation detail for Semigroup like (<$), readPrec,
readListPrec, log1p, etc. avoids clutter and breakage.
Heck, that way if you really want List somewhere in the name you can
personally import Data.List.NonEmpty qualified or ignore it and sconcat
entirely.
-Edward
On Thu, Dec 29, 2016 at 12:57 PM, Andreas Abel
Since "nonEmpty" is a predicate that could apply any kind of collection, not just lists, I am strongly -1 on such a proposal.
Similarly, "NonEmpty" misses a "List", it should be called "NonEmptyList".
--Andreas
On 29.12.2016 15:26, Henrik Nilsson wrote:
Hi,
On 12/29/2016 12:48 PM, Andreas Abel wrote:
What are the types and definitions of
nonEmpty, (:|), and the type constructor NonEmpty.
?
Must be something generic, overloaded, given the name...
Indeed, one would assume so, given the names.
But:
What are the types and definitions of
nonEmpty, (:|), and the type constructor NonEmpty.
?
See http://hackage.haskell.org/package/base-4.9.0.0/docs/ Data-List-NonEmpty.html
there is nothing generic at all about these:
I am assuming that the idea is that these three definitions will be made available for unqualified use (while all other library functions for programming with non-empty lists would have to be imported explicitly from Data.List.NonEmpty, as currently is the case).
But these are really poor names for something this specific being made available unqualified everywhere: there are lots of things that could be called "NonEmpty" or "nonEmpty", and ":|" is a perfectly good combinator name for other purposes.
So this addition would do little beside increasing the footprint of the Prelude and causing issues clashes with code that happens to use these names already.
To quote Yuras Shumovich from a related thread (Add readMaybe (and possibly readEither) to Prelude): "We should be careful with Prelude."
Additionally, as is evidenced by the type signatures of the module NonEmpty, the utility of keeping track of non-empty lists at the type level in a language like Haskell is in general limited (which is not to say that it cannot be very useful sometimes). Even in a language with dependent types the approach (of integrating properties with data types) is not always smooth as it may lead to a proliferation of different related but distinct types which quickly becomes clunky. As far as I am aware, solving this conundrum is still an open research problem.
(And nothing new under the sun, either: people familiar with Pascal or Ada will have had similar experiences with a proliferation of integral types of various ranges. In simple cases, very useful to ensure e.g. an array index is not out of bounds, but does not go very far.)
Finally, why single out "non-empty" specifically as a property worthy to keep track at the type level in the prelude? Why not lists of finite length as well, for example? That could help ensuring termination.
(Just to be clear: I am not proposing this. I am just saying that I can't see how adding variations of existing types with specific properties to the prelude possibly can result in a principled design for a language like Haskell as it currently stands.)
/Henrik
This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham.
This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- Andreas Abel <>< Du bist der geliebte Mensch.
Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden
andreas.abel@gu.se http://www2.tcs.ifi.lmu.de/~abel/ _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On Thu, 29 Dec 2016, Henrik Nilsson wrote:
I am assuming that the idea is that these three definitions will be made available for unqualified use (while all other library functions for programming with non-empty lists would have to be imported explicitly from Data.List.NonEmpty, as currently is the case).
This discussion and the one about readMaybe again boil down to the observation that many Haskell programmers seem to hate imports or the module system at all, that they invest a lot of work just to save a line of imports.
To quote Yuras Shumovich from a related thread (Add readMaybe (and possibly readEither) to Prelude): "We should be careful with Prelude."
+1
Additionally, as is evidenced by the type signatures of the module NonEmpty, the utility of keeping track of non-empty lists at the type level in a language like Haskell is in general limited (which is not to say that it cannot be very useful sometimes). Even in a language with dependent types the approach (of integrating properties with data types) is not always smooth as it may lead to a proliferation of different related but distinct types which quickly becomes clunky. As far as I am aware, solving this conundrum is still an open research problem.
I released the package non-negative 8 years ago and non-empty 4 years ago and could acquire some experience with them. My enthusiasm about non-negative declined considerably over time, since it did not catch bugs at compile but left me with errors at run-time where supposedly non-negative numbers turned out to be negative due to floating point issues. In contrast to that I am quite happy with non-empty. It allows me to document the non-emptiness of lists and Sets and Maps and makes me confident when using NonEmpty.head, NonEmpty.last, NonEmpty.maximum instead of their Prelude counterparts. Conversion to plain lists with NonEmpty.flatten is seldom enough to be painful. Only sometimes in a recursion it is difficult to get the types consistent, because a non-empty list as accumulator might become doubly non-empty temporarily. I think that for non-negative numbers a tool like Liquid Haskell will be the better solution.

I'm personally -1 on this proposal *at this time*. Adding these to the
footprint of Prelude means everybody who has written any data type with a
data constructor named :| breaks, every combinator named nonEmpty, NonEmpty
type or class... so we shouldn't do this lightly.
That said, Semigroup is slated to become a superclass of Monoid in 8.6 and
move into Prelude as part of the timeline on
https://prime.haskell.org/wiki/Libraries/Proposals
and Semigroup has sconcat as a member, which references NonEmpty. At that
point the case becomes much stronger, and the need to decide how to handle
sconcat for the Prelude acts as a forcing function for this decision.
On the other hand, we don't have many classes exported from Prelude
partially, but we do have them: Functor (<$), Read (readPrec,
readListPrec), Floating (log1p, expm1, etc.) come to mind as members we
avoid exporting from Prelude.
So while there is precedent for continuing to hide "messy" implementation
details, at that point the weight of simplicity of explanation may come
down on the other side of the argument.
With all that in mind I'm -1 if we're talking about adding this in 8.4, but
I'm largely neutral and maybe even weakly positive about it for 8.6 as part
of the larger Semigroup migration and would be happy to accept either the
hidden detail solution or a solution that dragged NonEmpty into base based
on community feedback.
-Edward
On Wed, Dec 28, 2016 at 2:39 PM, Yitzchak Gale
In continuation of Simon Jakobi's proposal for a small incremental change to the Prelude to make it more conducive to partial-function-free programming,
https://mail.haskell.org/pipermail/libraries/2016-December/027496.html
and after some encouragement from the community on reddit, I propose adding the basic constructors of NonEmpty to the Prelude: nonEmpty, (:|), and the type constructor NonEmpty.
In practice, users of NonEmpty will often still need a qualified import of Data.List.NonEmpty. But having the constructors available in the Prelude will make the use of NonEmpty more common, and will make programming without partial functions feel more natural and standard.
Note: This proposal is separate from Simon's and should not interfere with the acceptance of Simon's. But it is related in that it attempts to achieve the same goals.
Discussion period: Until the end of the discussion period of Simon's proposal.
Thanks, Yitz _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

-1 : I'm against this because NonEmpty is a special case of "lists with at least n elements", and n=1 doesn't feel like a particuar sweet spot. Once people are using NonEmpty everywhere, won't they need at least 2 elements when using tail to get a NonEmpty, etc? On the flip side, the "group" functions do provide some argument in favour, as the n=1 case is exactly the guarantee they provide for their output. On 28/12/2016 19:39, Yitzchak Gale wrote:
In continuation of Simon Jakobi's proposal for a small incremental change to the Prelude to make it more conducive to partial-function-free programming,
https://mail.haskell.org/pipermail/libraries/2016-December/027496.html
and after some encouragement from the community on reddit, I propose adding the basic constructors of NonEmpty to the Prelude: nonEmpty, (:|), and the type constructor NonEmpty.
In practice, users of NonEmpty will often still need a qualified import of Data.List.NonEmpty. But having the constructors available in the Prelude will make the use of NonEmpty more common, and will make programming without partial functions feel more natural and standard.
Note: This proposal is separate from Simon's and should not interfere with the acceptance of Simon's. But it is related in that it attempts to achieve the same goals.
Discussion period: Until the end of the discussion period of Simon's proposal.
Thanks, Yitz _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On Thu, 5 Jan 2017, Ganesh Sittampalam wrote:
-1 : I'm against this because NonEmpty is a special case of "lists with at least n elements", and n=1 doesn't feel like a particuar sweet spot. Once people are using NonEmpty everywhere, won't they need at least 2 elements when using tail to get a NonEmpty, etc?
Btw. my non-empty package provides a NonEmpty constructor that can be nested, such that you can have lists with at least two elements.
participants (7)
-
Andreas Abel
-
Edward Kmett
-
Ganesh Sittampalam
-
Henning Thielemann
-
Henrik Nilsson
-
Simon Jakobi
-
Yitzchak Gale