module Clean.Applicative(
module Clean.Functor,
Applicative(..),
ZipList(..),ZipTree(..),Backwards(..),
(*>),(<*),ap,
liftA,liftA2,liftA3,liftA4,
plusA,zeroA
) where
import Clean.Functor
import Clean.Classes
import Clean.Core
import Data.Tree
import Clean.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 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
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)
where repeat a = a: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
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
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 (liftA2 (&) xs fs)
ap = (<*>)
a *> b = flip const<$>a<*>b
a <* b = const<$>a<*>b
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 (*)