-- |A module describing applicative functors module SimpleH.Applicative( module SimpleH.Functor, Applicative(..), ZipList(..),ZipTree(..),Backwards(..), (*>),(<*),(<**>),ap,sequence_,traverse_,for_,forever, between, liftA,liftA2,liftA3,liftA4, plusA,zeroA,filter ) where import SimpleH.Functor import SimpleH.Classes import SimpleH.Core import Data.Tree import SimpleH.Foldable instance Applicative (Either a) instance Monad (Either a) where join (Right a) = a join (Left a) = Left a instance Applicative ((->) a) instance Semigroup b => Semigroup (a -> b) where (+) = plusA instance Monoid b => Monoid (a -> b) where zero = zeroA instance Ring b => Ring (a -> b) where (*) = timesA ; one = oneA instance Monad ((->) a) where join f x = f x x instance Monoid w => Applicative ((,) w) instance Monoid w => Monad ((,) w) where join ~(w,~(w',a)) = (w+w',a) instance Applicative [] instance Monad [] where join = fold instance (Unit f,Unit g) => Unit (FProd f g) where pure a = FProd (pure a,pure a) instance (Applicative f,Applicative g) => Applicative (FProd f g) where FProd ~(ff,fg) <*> FProd ~(xf,xg) = FProd (ff<*>xf,fg<*>xg) instance Applicative Tree instance Monad Tree where join (Node (Node a subs) subs') = Node a (subs + map join subs') instance (Applicative f,Applicative g) => Applicative (Compose f g) where Compose fs <*> Compose xs = Compose ((<*>)<$>fs<*>xs) deriving instance Unit Interleave instance Applicative Interleave instance Monad Interleave where join = fold {-| A wrapper type for lists with zipping Applicative instances, such that @ZipList [f1,...,fn] '<*>' ZipList [x1,...,xn] == ZipList [f1 x1,...,fn xn]@ -} newtype ZipList a = ZipList { getZipList :: [a] } instance Semigroup a => Semigroup (ZipList a) where (+) = plusA instance Monoid a => Monoid (ZipList a) where zero = zeroA instance Functor ZipList where map f (ZipList l) = ZipList (map f l) instance Unit ZipList where pure a = ZipList (repeat a) instance Applicative ZipList where ZipList fs <*> ZipList xs = ZipList (zip fs xs) where zip (f:fs) (x:xs) = f x:zip fs xs zip _ _ = [] deriving instance Foldable ZipList -- |The Tree equivalent to ZipList newtype ZipTree a = ZipTree (Tree a) instance Functor ZipTree where map f (ZipTree t) = ZipTree (map f t) instance Unit ZipTree where pure a = ZipTree (Node a (getZipList (pure (pure a)))) instance Applicative ZipTree where ZipTree (Node f fs) <*> ZipTree (Node x xs) = ZipTree (Node (f x) (getZipList ((<*>)<$>ZipList fs<*>ZipList xs))) deriving instance Foldable ZipTree -- |A wrapper for applicative functors with actions executed in the reverse order newtype Backwards f a = Backwards { forwards :: f a } deriving instance Semigroup (f a) => Semigroup (Backwards f a) deriving instance Monoid (f a) => Monoid (Backwards f a) deriving instance Ring (f a) => Ring (Backwards f a) deriving instance Unit f => Unit (Backwards f) deriving instance Functor f => Functor (Backwards f) instance Applicative f => Applicative (Backwards f) where Backwards fs <*> Backwards xs = Backwards (fs<**>xs) ap = (<*>) infixl 2 <*,*> infixl 2 <**> (*>) = liftA2 (flip const) (<*) = liftA2 const f <**> x = liftA2 (&) x f sequence_ = foldr (*>) (pure ()) traverse_ :: (Applicative f,Foldable t) => (a -> f b) -> t a -> f () traverse_ f = sequence_ . map f for_ = flip traverse_ forever m = undefined<$sequence_ (repeat m) liftA = map liftA2 f = \a b -> f<$>a<*>b liftA3 f = \a b c -> f<$>a<*>b<*>c liftA4 f = \a b c d -> f<$>a<*>b<*>c<*>d plusA = liftA2 (+) zeroA = pure zero oneA = pure one timesA = liftA2 (*) between start end p = liftA3 (\_ b _ -> b) start p end instance (Applicative f,Semigroup (g a)) => Semigroup (Compose f g a) where Compose f+Compose g = Compose ((+)<$>f<*>g) instance (Applicative f,Monoid (g a)) => Monoid (Compose f g a) where zero = Compose (pure zero)