Proposal: alpha-rename the type signatures of foldl, foldl', and scanl to be consistent with foldr and scanr

Gábor Lehel <[email protected]>
Newsgroups gmane.comp.lang.haskell.cvs.ghc,gmane.comp.lang.haskell.libraries
Message-ID <CAPNUp09AZPSKCPGm5uf43JZd=zcMgV_LEjgnQbjZ9gZkm83kHA@mail.gmail.com>
Currently we have:

    foldl :: (a -> b -> a) -> a -> [b] -> a

    foldr :: (a -> b -> b) -> b -> [a] -> b

I find this confusing. My brain doesn't do automatic alpha-renaming,
so I end up thinking that these types are very different because they
look very different. In fact, they are almost the same.
Embarrassingly, it took me longer than it took to understand monads,
GADTs, PolyKinds, and several other things before I realized it!

So I propose that we use 'a' consistently to denote the type of the
list elements, and 'b' to denote the type of the result:

    foldl :: (b -> a -> b) -> b -> [a] -> b

    foldr :: (a -> b -> b) -> b -> [a] -> b

making it obvious that the only difference is the order of parameters
to the accumulator.

The total change would be to replace

    Prelude.foldl :: (a -> b -> a) -> a -> [b] -> a
    Prelude.scanl :: (a -> b -> a) -> a -> [b] -> [a]
    Data.List.foldl' :: (a -> b -> a) -> a -> [b] -> a
    Data.Foldable.foldl :: (a -> b -> a) -> a -> t b -> a
    Data.Foldable.foldl' :: (a -> b -> a) -> a -> t b -> a

with

    Prelude.foldl :: (b -> a -> b) -> b -> [a] -> b
    Prelude.scanl :: (b -> a -> b) -> b -> [a] -> [b]
    Data.List.foldl' :: (b -> a -> b) -> b -> [a] -> b
    Data.Foldable.foldl :: (b -> a -> b) -> b -> t a -> b
    Data.Foldable.foldl' :: (b -> a -> b) -> b -> t a -> b

I've attached a patch.

Discussion period: 2 weeks

Previously discussed at: http://www.reddit.com/r/haskell/comments/10q2ls/

-- 
Your ship was destroyed in a monadic eruption.

_______________________________________________
Cvs-ghc mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-ghc
0001-alpha-rename-the-type-signatures-of-foldl-foldl-and-.patch (application/octet-stream, 3.3 KB)
From a351cc0eb850d1446668f19d9db0d7ac42a7edd3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=A1bor=20Lehel?= <[email protected]>
Date: Sun, 14 Oct 2012 16:23:53 +0200
Subject: [PATCH] alpha-rename the type signatures of foldl, foldl', and scanl to be consistent with foldr and scanr

---
 Data/Foldable.hs |    4 ++--
 Data/List.hs     |    8 ++++----
 GHC/List.lhs     |    4 ++--
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/Data/Foldable.hs b/Data/Foldable.hs
index 4449ca9..afd9afa 100644
--- a/Data/Foldable.hs
+++ b/Data/Foldable.hs
@@ -132,14 +132,14 @@ class Foldable t where
     -- | Left-associative fold of a structure.
     --
     -- @'foldl' f z = 'Prelude.foldl' f z . 'toList'@
-    foldl :: (a -> b -> a) -> a -> t b -> a
+    foldl :: (b -> a -> b) -> b -> t a -> b
     foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z
 
     -- | Left-associative fold of a structure.
     -- but with strict application of the operator.
     --
     -- @'foldl' f z = 'List.foldl'' f z . 'toList'@
-    foldl' :: (a -> b -> a) -> a -> t b -> a
+    foldl' :: (b -> a -> b) -> b -> t a -> b
     foldl' f z0 xs = foldr f' id xs z0
       where f' x k z = k $! f z x
 
diff --git a/Data/List.hs b/Data/List.hs
index c3d1a84..7a05939 100644
--- a/Data/List.hs
+++ b/Data/List.hs
@@ -45,8 +45,8 @@ module Data.List
 
    -- * Reducing lists (folds)
 
-   , foldl             -- :: (a -> b -> a) -> a -> [b] -> a
-   , foldl'            -- :: (a -> b -> a) -> a -> [b] -> a
+   , foldl             -- :: (b -> a -> b) -> b -> [a] -> b
+   , foldl'            -- :: (b -> a -> b) -> b -> [a] -> b
    , foldl1            -- :: (a -> a -> a) -> [a] -> a
    , foldl1'           -- :: (a -> a -> a) -> [a] -> a
    , foldr             -- :: (a -> b -> b) -> b -> [a] -> b
@@ -68,7 +68,7 @@ module Data.List
    -- * Building lists
 
    -- ** Scans
-   , scanl             -- :: (a -> b -> a) -> a -> [b] -> [a]
+   , scanl             -- :: (b -> a -> b) -> b -> [a] -> [b]
    , scanl1            -- :: (a -> a -> a) -> [a] -> [a]
    , scanr             -- :: (a -> b -> b) -> b -> [a] -> [b]
    , scanr1            -- :: (a -> a -> a) -> [a] -> [a]
@@ -1004,7 +1004,7 @@ unfoldr f b  =
 -- -----------------------------------------------------------------------------
 
 -- | A strict version of 'foldl'.
-foldl'           :: (a -> b -> a) -> a -> [b] -> a
+foldl'           :: (b -> a -> b) -> b -> [a] -> b
 #ifdef __GLASGOW_HASKELL__
 foldl' f z0 xs0 = lgo z0 xs0
     where lgo z []     = z
diff --git a/GHC/List.lhs b/GHC/List.lhs
index 5dfd1ac..b32cea9 100644
--- a/GHC/List.lhs
+++ b/GHC/List.lhs
@@ -166,7 +166,7 @@ filterFB c p x r | p x       = x `c` r
 -- can be inlined, and then (often) strictness-analysed,
 -- and hence the classic space leak on foldl (+) 0 xs
 
-foldl        :: (a -> b -> a) -> a -> [b] -> a
+foldl        :: (b -> a -> b) -> b -> [a] -> b
 foldl f z0 xs0 = lgo z0 xs0
              where
                 lgo z []     =  z
@@ -181,7 +181,7 @@ foldl f z0 xs0 = lgo z0 xs0
 --
 -- > last (scanl f z xs) == foldl f z xs.
 
-scanl                   :: (a -> b -> a) -> a -> [b] -> [a]
+scanl                   :: (b -> a -> b) -> b -> [a] -> [b]
 scanl f q ls            =  q : (case ls of
                                 []   -> []
                                 x:xs -> scanl f (f q x) xs)
-- 
1.7.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.