[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