module DeferredFolds.ToBeFoldled
where
import DeferredFolds.Prelude
import qualified DeferredFolds.Prelude as A
newtype ToBeFoldled input =
ToBeFoldled (forall output. (output -> input -> output) -> output -> output)
deriving instance Functor ToBeFoldled
instance Applicative ToBeFoldled where
pure x =
ToBeFoldled (\ step init -> step init x)
(<*>) = ap
instance Alternative ToBeFoldled where
empty =
ToBeFoldled (const id)
{-# INLINE (<|>) #-}
(<|>) (ToBeFoldled left) (ToBeFoldled right) =
ToBeFoldled (\ step init -> right step (left step init))
instance Monad ToBeFoldled where
return = pure
(>>=) (ToBeFoldled left) rightK =
ToBeFoldled $ \ step init ->
let
newStep output x =
case rightK x of
ToBeFoldled right ->
right step output
in left newStep init
instance MonadPlus ToBeFoldled where
mzero = empty
mplus = (<|>)
instance Semigroup (ToBeFoldled a) where
(<>) = (<|>)
instance Monoid (ToBeFoldled a) where
mempty = empty
mappend = (<>)
{-# INLINE foldl' #-}
foldl' :: (output -> input -> output) -> output -> ToBeFoldled input -> output
foldl' step init (ToBeFoldled run) = run step init
{-# INLINE fold #-}
fold :: Fold input output -> ToBeFoldled input -> output
fold (Fold step init extract) (ToBeFoldled run) = extract (run step init)
{-# INLINE foldable #-}
foldable :: Foldable foldable => foldable a -> ToBeFoldled a
foldable foldable = ToBeFoldled (\ step init -> A.foldl' step init foldable)