{-# LANGUAGE ExplicitForAll #-}
-- | Exports predefined Cirqs.
module Data.Cirq.Utils where
import Data.Cirq.Base as Cq
{-# LANGUAGE ExplicitForAll #-}
import Control.Arrow as Arr
cqTotal :: forall a. Num a => Cirq a a
cqTotal = cqAccum 0 (+)
-- ^ Keeps track of the total of numbers passed to it.
-- When a number is passed to it, the replacement function will add that number to its number,
-- and so on.
cqTotalM :: forall a. Monoid a => Cirq a a
cqTotalM = cqAccum mempty mappend
-- ^ Like total, but with arbitrary monoids instead of number and addition
cqProd :: forall a. Num a => Cirq a a
cqProd = cqAccum 1 (*)
-- ^ Like total, but with multiplication
-- The multiplicative dentity is 1, so it starts with 1.
cqIndex :: forall a b. Num b => b -> Cirq a b
cqIndex n = Cirq $ \_ -> (cqIndex (n + 1), n)
-- ^ Ignores input and returns parameter, replacement Cirq returns a value one higher than the previous value.
-- Effectively indexes when applied to lists using runCq.
cqMean :: forall a. Fractional a => Cirq a a
cqMean = (cqTotal &&& cqIndex 1) >>> arr (uncurry (/))
-- ^ Keeps two accumulators, one keeping a total and another keeping an index,
-- then divides total by the index.
-- Effectively calculates the mean of number passed so far when applied using runCq.
-- ! The concept of Cirq and many functions here are lifted from the Arrow Tutorial from Wikibooks' Hasell book.