[commit: ghc] master: Add Data.List.sortOn function (re #9004 and #2659) (44512e3)
git at git.haskell.org
git at git.haskell.org
Sat Apr 19 09:52:14 UTC 2014
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/44512e3c855d8fb36ab6580f4f97f842ebcf4c6c/ghc
>---------------------------------------------------------------
commit 44512e3c855d8fb36ab6580f4f97f842ebcf4c6c
Author: Alexander Berntsen <alexander at plaimi.net>
Date: Fri Apr 18 21:41:11 2014 +0200
Add Data.List.sortOn function (re #9004 and #2659)
`sortOn` sorts a list by comparing the results of a key function applied to each
element. `sortOn f` is equivalent to `sortBy . comparing f`, but has the
performance advantage of only evaluating `f` once for each element in the
input list.
Historical note: This was already proposed in 2008 as part of
http://www.haskell.org/pipermail/libraries/2008-October/010797.html
It was, however, the recent re-attempt
http://www.haskell.org/pipermail/libraries/2014-April/022489.html
that let `sortOn` make it into base at last. Maybe the other functions
mentioned in #2659 might be worth reconsidering as well.
>---------------------------------------------------------------
44512e3c855d8fb36ab6580f4f97f842ebcf4c6c
libraries/base/Data/List.hs | 14 ++++++++++++++
libraries/base/changelog.md | 2 ++
2 files changed, 16 insertions(+)
diff --git a/libraries/base/Data/List.hs b/libraries/base/Data/List.hs
index 09aed9d..7f66528 100644
--- a/libraries/base/Data/List.hs
+++ b/libraries/base/Data/List.hs
@@ -164,6 +164,7 @@ module Data.List
-- ** Ordered lists
, sort
+ , sortOn
, insert
-- * Generalized functions
@@ -207,6 +208,8 @@ module Data.List
import Data.Maybe
import Data.Char ( isSpace )
+import Data.Ord ( comparing )
+import Data.Tuple ( fst, snd )
import GHC.Num
import GHC.Real
@@ -957,6 +960,17 @@ rqpart cmp x (y:ys) rle rgt r =
#endif /* USE_REPORT_PRELUDE */
+-- | Sort a list by comparing the results of a key function applied to each
+-- element. @sortOn f@ is equivalent to @sortBy . comparing f@, but has the
+-- performance advantage of only evaluating @f@ once for each element in the
+-- input list. This is called the decorate-sort-undecorate paradigm, or
+-- Schwartzian transform.
+--
+-- /Since: 4.7.1.0/
+sortOn :: Ord b => (a -> b) -> [a] -> [a]
+sortOn f =
+ map snd . sortBy (comparing fst) . map (\x -> let y = f x in y `seq` (y, x))
+
-- | The 'unfoldr' function is a \`dual\' to 'foldr': while 'foldr'
-- reduces a list to a summary value, 'unfoldr' builds a list from
-- a seed value. The function takes the element and returns 'Nothing'
diff --git a/libraries/base/changelog.md b/libraries/base/changelog.md
index 75e7710..3011fdf 100644
--- a/libraries/base/changelog.md
+++ b/libraries/base/changelog.md
@@ -6,6 +6,8 @@
* Add reverse application operator `Data.Function.(&)`
+ * Add `Data.List.sortOn` sorting function
+
## 4.7.0.0 *Apr 2014*
* Bundled with GHC 7.8.1
More information about the ghc-commits
mailing list