-
Notifications
You must be signed in to change notification settings - Fork 28
Description
Currently foldl'
function has next type:
foldl' :: forall a b . (b -> a -> b) -> b -> [a] -> b
This type signature is not very convenient to use. Consider function where you want to insert elements of list one by one into HashSet
(this is trivial example, but in practice something structurally similar appears very often):
foo :: Hashable key => [key] -> HashSet key
foo = foldl' (flip HashSet.insert) mempty
You either add flip
or write your own function inside where
. Or use foldr
, but foldr
performance is abysmal and such implementation will have space leak (TODO: benchmark and profile to prove it). It's a common pattern in Haskell where data structure is the last argument of function. Because it's convenient to use so. But when you want to use this pattern with foldl'
you can't rely on eta-reduce anymore :( You can't just write
foo :: Hashable key => [key] -> HashSet key
foo = foldl' HashSet.insert mempty
So I propose to have our foldl'
with arguments changed:
foldl' :: forall a b . (a -> b -> b) -> b -> [a] -> b
This should be implemented using foldl'
from base
. And some benchmarks should be added as well. I checked GHC.List
module and didn't notice presence of foldl'
inside RULES
pragmas. So this change can be performed without performance penalties.
DRAWBACKS
- Unexpected arguments order for users of
foldl'
frombase
(shouldn't be very important because not many people usesfoldl'
) - Potential performance penalties if we implement
foldl'
in a wrong way.
ADVANTAGES
- More convenient library API.