Add Foldable1 to base
This is a proposal to add Foldable1 (non-empty Foldable
) to base
-- Data.Semigroup.Foldable
class Foldable f => Foldable1 f where
fold1 :: Semigroup m => f m -> m
foldMap1 :: Semigroup m => (a -> m) -> (f a -> m)
-- Possible methods
head1 :: f a -> a
last1 :: f a -> a
toNonEmpty :: f a -> NonEmpty a
along with instances and function that are only valid for non-empty structures (details: semigroupoids issue #49, github)
import qualified Data.Semigroup as S
minimum1, maximum1 :: (Ord a, Foldable1 f) => f a -> a
minimum1 = S.getMin . foldMap1 S.Min
maximum1 = S.getMax . foldMap1 S.Max
head1, last1 :: Foldable1 f => f a -> a
head1 = S.getFirst . foldMap1 S.First
last1 = S.getLast . foldMap1 S.Last
foldr1, foldl1 :: Foldable1 f => (a -> a -> a) -> (f a -> a)
foldr1 f = unimprove . foldMap1 (\a -> Diff (f a) a)
foldl1 f = unimprove . getDual . foldMap1 (\a -> Dual $ Diff (flip f a) a)
Adding foldM
, foldM_
, foldrM
and foldlM
for non-empty structures is also a possibility.
Currently these are partial functions in Foldable
. This proposal does not propose replacing partial Foldable
functions.
I wanted to test the waters before submitting it to the libraries mailing list. This may be controversial but it gives us a path to avoid partial functions in Foldable
.