{-# LANGUAGE CPP #-}
#if MIN_VERSION_base(4,9,0)
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
#endif
module Foundation.Collection.Foldable
( Foldable(..)
, Fold1able(..)
) where
import Basement.Compat.Base
import Foundation.Collection.Element
import Basement.NonEmpty
import Basement.Nat
import qualified Data.List
import qualified Basement.UArray as UV
import qualified Basement.Block as BLK
import qualified Basement.BoxedArray as BA
#if MIN_VERSION_base(4,9,0)
import qualified Basement.Sized.List as LN
import qualified Basement.Sized.Block as BLKN
#endif
class Foldable collection where
foldl' :: (a -> Element collection -> a) -> a -> collection -> a
foldr :: (Element collection -> a -> a) -> a -> collection -> a
foldr' :: (Element collection -> a -> a) -> a -> collection -> a
foldr' f z0 xs = foldl' f' id xs z0 where f' k x z = k $! f x z
class Foldable f => Fold1able f where
foldl1' :: (Element f -> Element f -> Element f) -> NonEmpty f -> Element f
foldr1 :: (Element f -> Element f -> Element f) -> NonEmpty f -> Element f
instance Foldable [a] where
foldr = Data.List.foldr
foldl' = Data.List.foldl'
instance UV.PrimType ty => Foldable (UV.UArray ty) where
foldr = UV.foldr
foldl' = UV.foldl'
instance Foldable (BA.Array ty) where
foldr = BA.foldr
foldl' = BA.foldl'
instance UV.PrimType ty => Foldable (BLK.Block ty) where
foldr = BLK.foldr
foldl' = BLK.foldl'
#if MIN_VERSION_base(4,9,0)
instance Foldable (LN.ListN n a) where
foldr = LN.foldr
foldl' = LN.foldl'
instance UV.PrimType ty => Foldable (BLKN.BlockN n ty) where
foldr = BLKN.foldr
foldl' = BLKN.foldl'
#endif
instance Fold1able [a] where
foldr1 f = Data.List.foldr1 f . getNonEmpty
foldl1' f = Data.List.foldl1' f . getNonEmpty
instance UV.PrimType ty => Fold1able (UV.UArray ty) where
foldr1 = UV.foldr1
foldl1' = UV.foldl1'
instance Fold1able (BA.Array ty) where
foldr1 = BA.foldr1
foldl1' = BA.foldl1'
instance UV.PrimType ty => Fold1able (BLK.Block ty) where
foldr1 = BLK.foldr1
foldl1' = BLK.foldl1'
#if MIN_VERSION_base(4,9,0)
instance (1 <= n) => Fold1able (LN.ListN n a) where
foldr1 f = LN.foldr1 f . getNonEmpty
foldl1' f = LN.foldl1' f . getNonEmpty
#endif