module Data.Fold.Internal
( SnocList(..)
, SnocList1(..)
, List1(..)
, Maybe'(..), maybe'
, Pair'(..)
, N(..)
, Tree(..)
, Tree1(..)
, An(..)
, Box(..)
) where
import Control.Applicative
import Data.Data (Data, Typeable)
import Data.Foldable
import Data.Monoid hiding (First, Last)
import Data.Proxy (Proxy(Proxy))
import Data.Reflection
import Data.Traversable
data SnocList a = Snoc (SnocList a) a | Nil
deriving (Eq,Ord,Show,Read,Typeable,Data)
instance Functor SnocList where
fmap f (Snoc xs x) = Snoc (fmap f xs) (f x)
fmap _ Nil = Nil
instance Foldable SnocList where
foldl f z m0 = go m0 where
go (Snoc xs x) = f (go xs) x
go Nil = z
foldMap f (Snoc xs x) = foldMap f xs `mappend` f x
foldMap _ Nil = mempty
instance Traversable SnocList where
traverse f (Snoc xs x) = Snoc <$> traverse f xs <*> f x
traverse _ Nil = pure Nil
data SnocList1 a = Snoc1 (SnocList1 a) a | First a
deriving (Eq,Ord,Show,Read,Typeable,Data)
instance Functor SnocList1 where
fmap f (Snoc1 xs x) = Snoc1 (fmap f xs) (f x)
fmap f (First a) = First (f a)
instance Foldable SnocList1 where
foldl f z m0 = go m0 where
go (Snoc1 xs x) = f (go xs) x
go (First a) = f z a
foldl1 f m0 = go m0 where
go (Snoc1 xs x) = f (go xs) x
go (First a) = a
foldMap f (Snoc1 xs x) = foldMap f xs `mappend` f x
foldMap f (First a) = f a
instance Traversable SnocList1 where
traverse f (Snoc1 xs x) = Snoc1 <$> traverse f xs <*> f x
traverse f (First a) = First <$> f a
data Maybe' a = Nothing' | Just' !a
deriving (Eq,Ord,Show,Read,Typeable,Data)
instance Foldable Maybe' where
foldMap _ Nothing' = mempty
foldMap f (Just' a) = f a
maybe' :: b -> (a -> b) -> Maybe' a -> b
maybe' _ f (Just' a) = f a
maybe' z _ Nothing' = z
newtype N a s = N { runN :: a }
deriving (Eq,Ord,Show,Read,Typeable,Data)
instance Reifies s (a -> a -> a, a) => Monoid (N a s) where
mempty = N $ snd $ reflect (Proxy :: Proxy s)
mappend (N a) (N b) = N $ fst (reflect (Proxy :: Proxy s)) a b
data Tree a
= Zero
| One a
| Two (Tree a) (Tree a)
deriving (Eq,Ord,Show,Read,Typeable,Data)
instance Functor Tree where
fmap _ Zero = Zero
fmap f (One a) = One (f a)
fmap f (Two a b) = Two (fmap f a) (fmap f b)
instance Foldable Tree where
foldMap _ Zero = mempty
foldMap f (One a) = f a
foldMap f (Two a b) = foldMap f a `mappend` foldMap f b
instance Traversable Tree where
traverse _ Zero = pure Zero
traverse f (One a) = One <$> f a
traverse f (Two a b) = Two <$> traverse f a <*> traverse f b
data Pair' a b = Pair' !a !b deriving (Eq,Ord,Show,Read,Typeable,Data)
instance (Monoid a, Monoid b) => Monoid (Pair' a b) where
mempty = Pair' mempty mempty
mappend (Pair' a b) (Pair' c d) = Pair' (mappend a c) (mappend b d)
newtype An a = An a deriving (Eq,Ord,Show,Read,Typeable,Data)
instance Functor An where
fmap f (An a) = An (f a)
instance Foldable An where
foldMap f (An a) = f a
instance Traversable An where
traverse f (An a) = An <$> f a
data Box a = Box a deriving (Eq,Ord,Show,Read,Typeable,Data)
instance Functor Box where
fmap f (Box a) = Box (f a)
instance Foldable Box where
foldMap f (Box a) = f a
instance Traversable Box where
traverse f (Box a) = Box <$> f a
data List1 a = Cons1 a (List1 a) | Last a
instance Functor List1 where
fmap f (Cons1 a as) = Cons1 (f a) (fmap f as)
fmap f (Last a) = Last (f a)
instance Foldable List1 where
foldMap f = go where
go (Cons1 a as) = f a `mappend` foldMap f as
go (Last a) = f a
foldr f z = go where
go (Cons1 a as) = f a (go as)
go (Last a) = f a z
foldr1 f = go where
go (Cons1 a as) = f a (go as)
go (Last a) = a
instance Traversable List1 where
traverse f (Cons1 a as) = Cons1 <$> f a <*> traverse f as
traverse f (Last a) = Last <$> f a
data Tree1 a = Bin1 (Tree1 a) (Tree1 a) | Tip1 a
instance Functor Tree1 where
fmap f (Bin1 as bs) = Bin1 (fmap f as) (fmap f bs)
fmap f (Tip1 a) = Tip1 (f a)
instance Foldable Tree1 where
foldMap f (Bin1 as bs) = foldMap f as `mappend` foldMap f bs
foldMap f (Tip1 a) = f a
instance Traversable Tree1 where
traverse f (Bin1 as bs) = Bin1 <$> traverse f as <*> traverse f bs
traverse f (Tip1 a) = Tip1 <$> f a