module Generics.OneLiner.Functions1 (
fmapADT
, foldMapADT
, traverseADT
, pureADT
, apADT
, bindADT
, mfixADT
) where
import Generics.OneLiner.ADT1
import Control.Applicative
import Control.Monad.Fix
import Data.Monoid
import Data.Foldable
import Data.Traversable
fmapADT :: (ADT1 t, Constraints t Functor) => (a -> b) -> t a -> t b
fmapADT f ta = builds (For :: For Functor) (\fld -> f (ta ! fld)) (\fld -> fmap f (ta !~ fld)) `at` ta
foldMapADT :: (ADT1 t, Constraints t Foldable, Monoid m) => (a -> m) -> t a -> m
foldMapADT f ta = mbuilds (For :: For Foldable) (\fld -> f (ta ! fld)) (\fld -> foldMap f (ta !~ fld)) `at` ta
traverseADT :: (ADT1 t, Constraints t Traversable, Applicative f) => (a -> f b) -> t a -> f (t b)
traverseADT f ta = buildsA (For :: For Traversable) (\fld -> f (ta ! fld)) (\fld -> traverse f (ta !~ fld)) `at` ta
pureADT :: (ADT1Record t, Constraints t Applicative) => a -> t a
pureADT a = build (For :: For Applicative) (const a) (const $ pure a)
apADT :: (ADT1Record t, Constraints t Applicative) => t (a -> b) -> t a -> t b
apADT tf ta = build (For :: For Applicative) (\fld -> (tf ! fld) (ta ! fld)) (\fld -> (tf !~ fld) <*> (ta !~ fld))
bindADT :: (ADT1Record t, Constraints t Monad) => t a -> (a -> t b) -> t b
bindADT ta f = build (For :: For Monad) (\fld -> f (ta ! fld) ! fld) (\fld -> (ta !~ fld) >>= ((!~ fld) . f))
mfixADT :: (ADT1Record t, Constraints t MonadFix) => (a -> t a) -> t a
mfixADT f = build (For :: For MonadFix) (\fld -> fix ((! fld) . f)) (\fld -> mfix ((!~ fld) . f))