module Data.Vinyl.Functor where
import Control.Applicative
import Data.Foldable
import Data.Traversable
import Foreign.Storable
newtype Identity a
= Identity { getIdentity :: a }
deriving ( Functor
, Foldable
, Traversable
, Storable
)
data Thunk a
= Thunk { getThunk :: a }
deriving ( Functor
, Foldable
, Traversable
)
newtype Lift (op :: l -> l' -> *) (f :: k -> l) (g :: k -> l') (x :: k)
= Lift { getLift :: op (f x) (g x) }
newtype Compose (f :: l -> *) (g :: k -> l) (x :: k)
= Compose { getCompose :: f (g x) }
deriving (Storable)
type f :. g = Compose f g
newtype Const (a :: *) (b :: k)
= Const { getConst :: a }
deriving ( Functor
, Foldable
, Traversable
, Storable
)
instance (Functor f, Functor g) => Functor (Compose f g) where
fmap f (Compose x) = Compose (fmap (fmap f) x)
instance (Foldable f, Foldable g) => Foldable (Compose f g) where
foldMap f (Compose t) = foldMap (foldMap f) t
instance (Traversable f, Traversable g) => Traversable (Compose f g) where
traverse f (Compose t) = Compose <$> traverse (traverse f) t
instance (Applicative f, Applicative g) => Applicative (Compose f g) where
pure x = Compose (pure (pure x))
Compose f <*> Compose x = Compose ((<*>) <$> f <*> x)
instance Applicative Identity where
pure = Identity
Identity f <*> Identity x = Identity (f x)
instance Monad Identity where
return = Identity
Identity x >>= f = f x
instance Show a => Show (Identity a) where
show (Identity x) = show x
instance Applicative Thunk where
pure = Thunk
(Thunk f) <*> (Thunk x) = Thunk (f x)
instance Monad Thunk where
return = Thunk
(Thunk x) >>= f = f x
instance Show a => Show (Thunk a) where
show (Thunk x) = show x
instance (Functor f, Functor g) => Functor (Lift (,) f g) where
fmap f (Lift (x, y)) = Lift (fmap f x, fmap f y)
instance (Functor f, Functor g) => Functor (Lift Either f g) where
fmap f (Lift (Left x)) = Lift . Left . fmap f $ x
fmap f (Lift (Right x)) = Lift . Right . fmap f $ x
instance (Applicative f, Applicative g) => Applicative (Lift (,) f g) where
pure x = Lift (pure x, pure x)
Lift (f, g) <*> Lift (x, y) = Lift (f <*> x, g <*> y)