{-# LANGUAGE Safe #-}
{-# LANGUAGE BangPatterns #-}
module Relude.Extra.Foldable
( foldlSC
, average
) where
import Relude
foldlSC :: forall t b a. Foldable t => (b -> a -> Either b b) -> b -> t a -> b
foldlSC :: forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> Either b b) -> b -> t a -> b
foldlSC b -> a -> Either b b
f = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> (b -> b) -> b -> b
go forall a. a -> a
id
where
go :: a -> (b -> b) -> b -> b
go :: a -> (b -> b) -> b -> b
go a
x b -> b
k b
z = case b -> a -> Either b b
f b
z a
x of
Left b
l -> b
l
Right b
r -> b -> b
k b
r
{-# INLINE foldlSC #-}
average :: forall a f . (Foldable f, Fractional a) => f a -> Maybe a
average :: forall a (f :: * -> *).
(Foldable f, Fractional a) =>
f a -> Maybe a
average f a
xs
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null f a
xs = forall a. Maybe a
Nothing
| Bool
otherwise = forall a. a -> Maybe a
Just
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall a. Fractional a => a -> a -> a
(/)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\(!a
total, !a
count) a
x -> (a
total forall a. Num a => a -> a -> a
+ a
x, a
count forall a. Num a => a -> a -> a
+ a
1)) (a
0,a
0)
forall a b. (a -> b) -> a -> b
$ f a
xs
{-# INLINE average #-}