[PATCH 0/3] Implement nand/nor/nany/nall in Data.List

Hi. I'm a complete GHC newbie (and, really, a Haskell newbie still as well). To dive in and learn, I hacked together this. I did it primarily to familiarise myself with GHC workflow, formalities and procedures. Things like style conventions, using Trac, learning how to build GHC, how the files are structured and so on. However, my primary intention of learning does not mean that I don't find these patches valuable. I'm sick of typing (not . and), and even more sick of reading it. I find nand much more intuitive to read. Herbert told me to send these here since they affect base. I can imagine people are vary of putting stuff in base, and certainly prelude. But if I seem ignorant and ahistorical, that's because I *am*. So please, if there is something wrong with my patches, don't hesitate to educate me. Learning the ways of GHC hacking is after all my long-term goal. :-) Alexander Berntsen (3): Implement nand, nor, nany and nall in Data.List Inline nand, nor, nany and nall Put nand, nor, nany and nall in Prelude Data/List.hs | 4 ++++ GHC/List.lhs | 38 ++++++++++++++++++++++++++++++++++++-- Prelude.hs | 2 +- changelog.md | 3 +++ 4 files changed, 44 insertions(+), 3 deletions(-) -- 1.8.3.2

Implement negation-shorthands for `and`, `or`, `any` and `all` in Data.List: `nand`, `nor`, `nany`, `nall`. These functions compose `not` with `and`, `or`, `any` and `all` respectively. The rationale is less typing, and a more readable and immediately obvious way of doing this. The added namespace pollution should not be dramatic. If someone has defined the negations of `and` etc. elsewhere, they have likely defined `and` etc. as well. --- Data/List.hs | 4 ++++ GHC/List.lhs | 34 ++++++++++++++++++++++++++++++++-- changelog.md | 3 +++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/Data/List.hs b/Data/List.hs index 09aed9d..6675dfc 100644 --- a/Data/List.hs +++ b/Data/List.hs @@ -53,8 +53,12 @@ module Data.List , concatMap , and , or + , nand + , nor , any , all + , nany + , nall , sum , product , maximum diff --git a/GHC/List.lhs b/GHC/List.lhs index e004ded..a8b8950 100644 --- a/GHC/List.lhs +++ b/GHC/List.lhs @@ -25,8 +25,8 @@ module GHC.List ( foldl, scanl, scanl1, foldr, foldr1, scanr, scanr1, iterate, repeat, replicate, cycle, take, drop, splitAt, takeWhile, dropWhile, span, break, - reverse, and, or, - any, all, elem, notElem, lookup, + reverse, and, or, nand, nor, + any, all, nany, nall, elem, notElem, lookup, concatMap, zip, zip3, zipWith, zipWith3, unzip, unzip3, errorEmptyList, @@ -524,6 +524,22 @@ or (x:xs) = x || or xs #-} #endif +-- | 'nand' returns the negated conjunction of a Boolean list. For the result +-- to be 'False', the list must be finite; 'True', however, results from a +-- 'False' value at a finite index of a finite or infinite list. +-- +-- /Since: 4.7.0.0/ +nand :: [Bool] -> Bool +nand = not . and + +-- | 'nor' returns the negated disjunction of a Boolean list. For the result +-- to be 'True', the list must be finite; 'False', however, results from a +-- 'True' value at a finite index of a finite or infinite list. +-- +-- /Since: 4.7.0.0/ +nor :: [Bool] -> Bool +nor = not . or + -- | Applied to a predicate and a list, 'any' determines if any element -- of the list satisfies the predicate. For the result to be -- 'False', the list must be finite; 'True', however, results from a 'True' @@ -556,6 +572,20 @@ all p (x:xs) = p x && all p xs #-} #endif +-- | Applied to a predicate and a list, 'nany' determines if no element +-- of the list satisfies the predicate. For the result to be +-- 'True', the list must be finite; 'False', however, results from a 'True' +-- value for the predicate applied to an element at a finite index of a finite or infinite list. +nany :: (a -> Bool) -> [a] -> Bool +nany p = not . any p + +-- | Applied to a predicate and a list, 'nall' determines if not all elements +-- of the list satisfy the predicate. For the result to be +-- 'False', the list must be finite; 'True', however, results from a 'False' +-- value for the predicate applied to an element at a finite index of a finite or infinite list. +nall :: (a -> Bool) -> [a] -> Bool +nall p = not . all p + -- | 'elem' is the list membership predicate, usually written in infix form, -- e.g., @x \`elem\` xs@. For the result to be -- 'False', the list must be finite; 'True', however, results from an element equal to @x@ found at a finite index of a finite or infinite list. diff --git a/changelog.md b/changelog.md index 88ceec5..20c90f7 100644 --- a/changelog.md +++ b/changelog.md @@ -125,4 +125,7 @@ * Remove deprecated function `unsafePerformIO` export from `Foreign` (still available via `System.IO.Unsafe.unsafePerformIO`). + * Implement negation-shortands for `and`, `or`, `any` and `all` in + `Data.List`: `nand`, `nor`, `nany`, and `nall`. + * Various fixes and other improvements (see Git history for full details). -- 1.8.3.2

<1393513982-8917-2-git-send-email-alexander@plaimi.net>
On Thu, 27 Feb 2014 16:13:00 +0100, Alexander Berntsen
Implement negation-shorthands for `and`, `or`, `any` and `all` in Data.List: `nand`, `nor`, `nany`, `nall`. These functions compose `not` with `and`, `or`, `any` and `all` respectively.
In lens we have ‘none’ for what you call nany, which I find much more readable and clear. I don't like ‘nall’ either but I don't know a better term for it. nand/nor at least are in widespread use outside of this patch, so I don't find them to be too confusing.

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 On 27/02/14 16:44, Niklas Haas wrote:
In lens we have ‘none’ for what you call nany, which I find much more readable and clear. I don't like ‘nall’ either but I don't know a better term for it. nand/nor at least are in widespread use outside of this patch, so I don't find them to be too confusing. I agree that `none' is more readable than `nany' (though I have seen `nany' used elsewhere). However, I couldn't think of a better name for `nall' -- and `nand' and `nor' are both very common nomenclature. As such, I just settled for consistency.
Alexander alexander@plaimi.net https://secure.plaimi.net/~alexander -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iF4EAREIAAYFAlMPX+QACgkQRtClrXBQc7XvAQEAkGAn2Dw0WJMD24BPSJFLbB5r sQmrVc/+yWokEAc7LMQBAIQHnx+gWAFdjkD0R0nophjl4hm82vHPpkiyqWr0nDhN =wYoY -----END PGP SIGNATURE-----

Nexist
On Thursday, February 27, 2014, Alexander Berntsen
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
On 27/02/14 16:44, Niklas Haas wrote:
In lens we have ‘none’ for what you call nany, which I find much more readable and clear. I don't like ‘nall’ either but I don't know a better term for it. nand/nor at least are in widespread use outside of this patch, so I don't find them to be too confusing. I agree that `none' is more readable than `nany' (though I have seen `nany' used elsewhere). However, I couldn't think of a better name for `nall' -- and `nand' and `nor' are both very common nomenclature. As such, I just settled for consistency.
Alexander alexander@plaimi.net javascript:; https://secure.plaimi.net/~alexander -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
iF4EAREIAAYFAlMPX+QACgkQRtClrXBQc7XvAQEAkGAn2Dw0WJMD24BPSJFLbB5r sQmrVc/+yWokEAc7LMQBAIQHnx+gWAFdjkD0R0nophjl4hm82vHPpkiyqWr0nDhN =wYoY -----END PGP SIGNATURE----- _______________________________________________ Libraries mailing list Libraries@haskell.org javascript:; http://www.haskell.org/mailman/listinfo/libraries

Hello Alexander, While the patches are nicely done, I'm -1 on these additions, as I don't think there's enough value (in terms of Fairbairn threshold) to have these definitions added. Fwiw, I'd go even as far as saying that I wouldn't miss it if `Data.List.{and,or}` weren't defined in `base` as I'd rather use the 'All' and 'Any' newtypes with their Monoid instances or just `{all,any} id`, given that `Data.List{all,any}` are already taken by `map`-preprocessed versions of `and`/`or`. Cheers, On 2014-02-27 at 16:13:00 +0100, Alexander Berntsen wrote: [...]
+nand :: [Bool] -> Bool +nand = not . and
[...]
+nor :: [Bool] -> Bool +nor = not . or

I'm with Herbert on the -1.
They are easy enough compositions, so there is the Fairbairn threshold
argument, but then there is the fact that Data.List is a common unqualified
import, and that Data.Foldable _also_ exports versions of these
combinators, so for consistency would want these, and as that is heading
into the Prelude, the namespace pollution just gets worse.
-Edward
On Thu, Feb 27, 2014 at 12:28 PM, Herbert Valerio Riedel
Hello Alexander,
While the patches are nicely done, I'm -1 on these additions, as I don't think there's enough value (in terms of Fairbairn threshold) to have these definitions added.
Fwiw, I'd go even as far as saying that I wouldn't miss it if `Data.List.{and,or}` weren't defined in `base` as I'd rather use the 'All' and 'Any' newtypes with their Monoid instances or just `{all,any} id`, given that `Data.List{all,any}` are already taken by `map`-preprocessed versions of `and`/`or`.
Cheers,
On 2014-02-27 at 16:13:00 +0100, Alexander Berntsen wrote:
[...]
+nand :: [Bool] -> Bool +nand = not . and
[...]
+nor :: [Bool] -> Bool +nor = not . or
Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

--- GHC/List.lhs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/GHC/List.lhs b/GHC/List.lhs index a8b8950..7fb751a 100644 --- a/GHC/List.lhs +++ b/GHC/List.lhs @@ -530,6 +530,7 @@ or (x:xs) = x || or xs -- -- /Since: 4.7.0.0/ nand :: [Bool] -> Bool +{-# INLINE nand #-} nand = not . and -- | 'nor' returns the negated disjunction of a Boolean list. For the result @@ -538,6 +539,7 @@ nand = not . and -- -- /Since: 4.7.0.0/ nor :: [Bool] -> Bool +{-# INLINE nor #-} nor = not . or -- | Applied to a predicate and a list, 'any' determines if any element @@ -577,6 +579,7 @@ all p (x:xs) = p x && all p xs -- 'True', the list must be finite; 'False', however, results from a 'True' -- value for the predicate applied to an element at a finite index of a finite or infinite list. nany :: (a -> Bool) -> [a] -> Bool +{-# INLINE nany #-} nany p = not . any p -- | Applied to a predicate and a list, 'nall' determines if not all elements @@ -584,6 +587,7 @@ nany p = not . any p -- 'False', the list must be finite; 'True', however, results from a 'False' -- value for the predicate applied to an element at a finite index of a finite or infinite list. nall :: (a -> Bool) -> [a] -> Bool +{-# INLINE nall #-} nall p = not . all p -- | 'elem' is the list membership predicate, usually written in infix form, -- 1.8.3.2

With regard to this patch (disregarding all the other things that people
have weighed in on).... Does it actually do anything? These are all very
short functions; I'd rather expect that GHC (and other compilers) would
decide to inline them itself.
Hope you're not getting too discouraged. :)
-- Dan
On Thu, Feb 27, 2014 at 10:13 AM, Alexander Berntsen
--- GHC/List.lhs | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/GHC/List.lhs b/GHC/List.lhs index a8b8950..7fb751a 100644 --- a/GHC/List.lhs +++ b/GHC/List.lhs @@ -530,6 +530,7 @@ or (x:xs) = x || or xs -- -- /Since: 4.7.0.0/ nand :: [Bool] -> Bool +{-# INLINE nand #-} nand = not . and
-- | 'nor' returns the negated disjunction of a Boolean list. For the result @@ -538,6 +539,7 @@ nand = not . and -- -- /Since: 4.7.0.0/ nor :: [Bool] -> Bool +{-# INLINE nor #-} nor = not . or
-- | Applied to a predicate and a list, 'any' determines if any element @@ -577,6 +579,7 @@ all p (x:xs) = p x && all p xs -- 'True', the list must be finite; 'False', however, results from a 'True' -- value for the predicate applied to an element at a finite index of a finite or infinite list. nany :: (a -> Bool) -> [a] -> Bool +{-# INLINE nany #-} nany p = not . any p
-- | Applied to a predicate and a list, 'nall' determines if not all elements @@ -584,6 +587,7 @@ nany p = not . any p -- 'False', the list must be finite; 'True', however, results from a 'False' -- value for the predicate applied to an element at a finite index of a finite or infinite list. nall :: (a -> Bool) -> [a] -> Bool +{-# INLINE nall #-} nall p = not . all p
-- | 'elem' is the list membership predicate, usually written in infix form, -- 1.8.3.2
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 On 27/02/14 18:38, Dan Doel wrote:
With regard to this patch (disregarding all the other things that people have weighed in on).... Does it actually do anything? These are all very short functions; I'd rather expect that GHC (and other compilers) would decide to inline them itself. I honestly do not know if GHC does this automatically. If someone can give me an answer with an explanation, that would be interesting.
- -- Alexander alexander@plaimi.net https://secure.plaimi.net/~alexander -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iF4EAREIAAYFAlMPeyQACgkQRtClrXBQc7VaBAD/V5W4WX464O8Kl45V8MkmbI3W SFfwwtlgHyoThbR5UI8A/3vAKk3y6Mgydk6Q8+fj9HM34dzqRRbCUchRs8Wjl1CD =mMzW -----END PGP SIGNATURE-----

Again, if 'and' and 'or' are exposed without it being a problem, 'nand' and 'nor' could be too without causing a dramatic namespace pollution. --- Prelude.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Prelude.hs b/Prelude.hs index 6be7846..79e3868 100644 --- a/Prelude.hs +++ b/Prelude.hs @@ -83,7 +83,7 @@ module Prelude ( -- ** Reducing lists (folds) foldl, foldl1, foldr, foldr1, -- *** Special folds - and, or, any, all, + and, or, nand, nor, any, all, nany, nall, sum, product, concat, concatMap, maximum, minimum, -- 1.8.3.2

and and or have been exposed in the Prelude for 22+ years. They were in by
Haskell 1.2 from 1992 at latest, and where possibly around earlier.
Any pain they cause is *long* since over.
Adding nand and nor for trivial compositions causes fresh pain for anyone
already using those names ... to save 3 characters.
-Edward
On Thu, Feb 27, 2014 at 10:13 AM, Alexander Berntsen
Again, if 'and' and 'or' are exposed without it being a problem, 'nand' and 'nor' could be too without causing a dramatic namespace pollution. --- Prelude.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Prelude.hs b/Prelude.hs index 6be7846..79e3868 100644 --- a/Prelude.hs +++ b/Prelude.hs @@ -83,7 +83,7 @@ module Prelude ( -- ** Reducing lists (folds) foldl, foldl1, foldr, foldr1, -- *** Special folds - and, or, any, all, + and, or, nand, nor, any, all, nany, nall, sum, product, concat, concatMap, maximum, minimum, -- 1.8.3.2
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Thanks for the patches. This is a -1 vote from me: in general lately the
trend has been against adding shorthand functions that can be expressed as
the trivial combination of a few other combinators, especially in base.
On Thu, Feb 27, 2014 at 7:12 AM, Alexander Berntsen
Hi. I'm a complete GHC newbie (and, really, a Haskell newbie still as well). To dive in and learn, I hacked together this.
I did it primarily to familiarise myself with GHC workflow, formalities and procedures. Things like style conventions, using Trac, learning how to build GHC, how the files are structured and so on.
However, my primary intention of learning does not mean that I don't find these patches valuable. I'm sick of typing (not . and), and even more sick of reading it. I find nand much more intuitive to read.
Herbert told me to send these here since they affect base. I can imagine people are vary of putting stuff in base, and certainly prelude. But if I seem ignorant and ahistorical, that's because I *am*. So please, if there is something wrong with my patches, don't hesitate to educate me. Learning the ways of GHC hacking is after all my long-term goal. :-)
Alexander Berntsen (3): Implement nand, nor, nany and nall in Data.List Inline nand, nor, nany and nall Put nand, nor, nany and nall in Prelude
Data/List.hs | 4 ++++ GHC/List.lhs | 38 ++++++++++++++++++++++++++++++++++++-- Prelude.hs | 2 +- changelog.md | 3 +++ 4 files changed, 44 insertions(+), 3 deletions(-)
-- 1.8.3.2
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
--
Gregory Collins

Agreed, -1 for me too for the same reason.
Erik
On Thu, Feb 27, 2014 at 5:17 PM, Gregory Collins
Thanks for the patches. This is a -1 vote from me: in general lately the trend has been against adding shorthand functions that can be expressed as the trivial combination of a few other combinators, especially in base.
On Thu, Feb 27, 2014 at 7:12 AM, Alexander Berntsen
wrote: Hi. I'm a complete GHC newbie (and, really, a Haskell newbie still as well). To dive in and learn, I hacked together this.
I did it primarily to familiarise myself with GHC workflow, formalities and procedures. Things like style conventions, using Trac, learning how to build GHC, how the files are structured and so on.
However, my primary intention of learning does not mean that I don't find these patches valuable. I'm sick of typing (not . and), and even more sick of reading it. I find nand much more intuitive to read.
Herbert told me to send these here since they affect base. I can imagine people are vary of putting stuff in base, and certainly prelude. But if I seem ignorant and ahistorical, that's because I *am*. So please, if there is something wrong with my patches, don't hesitate to educate me. Learning the ways of GHC hacking is after all my long-term goal. :-)
Alexander Berntsen (3): Implement nand, nor, nany and nall in Data.List Inline nand, nor, nany and nall Put nand, nor, nany and nall in Prelude
Data/List.hs | 4 ++++ GHC/List.lhs | 38 ++++++++++++++++++++++++++++++++++++-- Prelude.hs | 2 +- changelog.md | 3 +++ 4 files changed, 44 insertions(+), 3 deletions(-)
-- 1.8.3.2
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
-- Gregory Collins
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

On Thu, Feb 27, 2014 at 10:12 PM, Alexander Berntsen
Herbert told me to send these here since they affect base. I can imagine people are vary of putting stuff in base, and certainly prelude. But if I seem ignorant and ahistorical, that's because I *am*. So please, if there is something wrong with my patches, don't hesitate to educate me. Learning the ways of GHC hacking is after all my long-term goal. :-)
Hi Alexander, It's hard to explain the general nervousness with modifying prelude + base. It's like a shared commons where rapid changes cause confusion. The general wisdom is that it's very easy to add idiomatic functions to one's kit. And by kit, I mean something like John Goerzen's MissingH. The big, silent shops that use Haskell commercially all have their own kits. -- Kim-Ee

Hi Alexander,
Glad to see your getting familiar with GHC. :)
Unfortunately I will have to agree with the other comments in this thread
that adding these simple compositions isn't really worth it (especially not
in the Prelude.)
On Thu, Feb 27, 2014 at 4:12 PM, Alexander Berntsen
Hi. I'm a complete GHC newbie (and, really, a Haskell newbie still as well). To dive in and learn, I hacked together this.
I did it primarily to familiarise myself with GHC workflow, formalities and procedures. Things like style conventions, using Trac, learning how to build GHC, how the files are structured and so on.
However, my primary intention of learning does not mean that I don't find these patches valuable. I'm sick of typing (not . and), and even more sick of reading it. I find nand much more intuitive to read.
Herbert told me to send these here since they affect base. I can imagine people are vary of putting stuff in base, and certainly prelude. But if I seem ignorant and ahistorical, that's because I *am*. So please, if there is something wrong with my patches, don't hesitate to educate me. Learning the ways of GHC hacking is after all my long-term goal. :-)
Alexander Berntsen (3): Implement nand, nor, nany and nall in Data.List Inline nand, nor, nany and nall Put nand, nor, nany and nall in Prelude
Data/List.hs | 4 ++++ GHC/List.lhs | 38 ++++++++++++++++++++++++++++++++++++-- Prelude.hs | 2 +- changelog.md | 3 +++ 4 files changed, 44 insertions(+), 3 deletions(-)
-- 1.8.3.2
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
participants (10)
-
Alexander Berntsen
-
Carter Schonwald
-
Dan Doel
-
Edward Kmett
-
Erik Hesselink
-
Gregory Collins
-
Herbert Valerio Riedel
-
Johan Tibell
-
Kim-Ee Yeoh
-
Niklas Haas