packages feed

gambler-0.0.0.0: source/Fold/Nonempty/Utilities.hs

module Fold.Nonempty.Utilities where

import Fold.Nonempty.Type

import Control.Applicative (Applicative, liftA2)
import Data.Functor (fmap)
import Fold.Pure.Type (Fold (Fold))

import qualified Fold.Pure.Type as Pure

{-| Allows to continue feeding a fold even after passing it to a function
that closes it -}
duplicate :: NonemptyFold a b -> NonemptyFold a (Fold a b)
duplicate NonemptyFold{ initial, step, extract } =
    NonemptyFold{ initial, step, extract = \x -> Fold
        { Pure.initial = x, Pure.step, Pure.extract } }

{-| @(premap f folder)@ returns a new fold where @f@ is applied at each step -}
premap :: (a -> b) -> NonemptyFold b r -> NonemptyFold a r
premap f NonemptyFold{ initial, step, extract } =
    NonemptyFold{ initial = \a -> initial (f a),
        step = \x a -> step x (f a), extract }

{-| Nest a fold in an applicative -}
nest :: Applicative f => NonemptyFold a b -> NonemptyFold (f a) (f b)
nest NonemptyFold{ initial, step, extract } = NonemptyFold
    { initial = fmap initial, step = liftA2 step, extract = fmap extract }