linear-generics-0.1.0.0: tests/Generics/Deriving/Functor.hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeSynonymInstances #-}
#if __GLASGOW_HASKELL__ >= 701
{-# LANGUAGE DefaultSignatures #-}
#endif
#if __GLASGOW_HASKELL__ >= 705
{-# LANGUAGE PolyKinds #-}
#endif
#if __GLASGOW_HASKELL__ >= 708
{-# LANGUAGE EmptyCase #-}
#endif
#if __GLASGOW_HASKELL__ >= 710
{-# LANGUAGE Safe #-}
#elif __GLASGOW_HASKELL__ >= 701
{-# LANGUAGE Trustworthy #-}
#endif
module Generics.Deriving.Functor (
-- * Generic Functor class
GFunctor(..)
-- * Default method
, gmapdefault
-- * Internal Functor class
, GFunctor'(..)
) where
import Control.Applicative (Const, ZipList)
import qualified Data.Monoid as Monoid (First, Last, Product, Sum)
import Data.Monoid (Dual)
import Generics.Linear
#if MIN_VERSION_base(4,4,0)
import Data.Complex (Complex)
#endif
#if MIN_VERSION_base(4,6,0)
import Data.Ord (Down)
#else
import GHC.Exts (Down)
#endif
#if MIN_VERSION_base(4,7,0)
import Data.Proxy (Proxy)
#endif
#if MIN_VERSION_base(4,8,0)
import Data.Functor.Identity (Identity)
import Data.Monoid (Alt)
#endif
#if MIN_VERSION_base(4,9,0)
import qualified Data.Functor.Product as Functor (Product)
import qualified Data.Functor.Sum as Functor (Sum)
import Data.Functor.Compose (Compose)
import Data.List.NonEmpty (NonEmpty)
import qualified Data.Semigroup as Semigroup (First, Last)
import Data.Semigroup (Arg, Max, Min, WrappedMonoid)
#endif
--------------------------------------------------------------------------------
-- Generic fmap
--------------------------------------------------------------------------------
class GFunctor' f where
gmap' :: (a -> b) -> f a -> f b
instance GFunctor' V1 where
gmap' _ x = case x of
#if __GLASGOW_HASKELL__ >= 708
{}
#else
!_ -> error "Void gmap"
#endif
instance GFunctor' U1 where
gmap' _ U1 = U1
instance GFunctor' Par1 where
gmap' f (Par1 a) = Par1 (f a)
instance GFunctor' (K1 i c) where
gmap' _ (K1 a) = K1 a
instance GFunctor' f => GFunctor' (M1 i c f) where
gmap' f (M1 a) = M1 (gmap' f a)
instance GFunctor' f => GFunctor' (MP1 m f) where
gmap' f (MP1 a) = MP1 (gmap' f a)
instance (GFunctor' f, GFunctor' g) => GFunctor' (f :+: g) where
gmap' f (L1 a) = L1 (gmap' f a)
gmap' f (R1 a) = R1 (gmap' f a)
instance (GFunctor' f, GFunctor' g) => GFunctor' (f :*: g) where
gmap' f (a :*: b) = gmap' f a :*: gmap' f b
instance (GFunctor' f, GFunctor g) => GFunctor' (f :.: g) where
gmap' f (Comp1 x) = Comp1 (gmap' (gmap f) x)
instance GFunctor' UAddr where
gmap' _ (UAddr a) = UAddr a
instance GFunctor' UChar where
gmap' _ (UChar c) = UChar c
instance GFunctor' UDouble where
gmap' _ (UDouble d) = UDouble d
instance GFunctor' UFloat where
gmap' _ (UFloat f) = UFloat f
instance GFunctor' UInt where
gmap' _ (UInt i) = UInt i
instance GFunctor' UWord where
gmap' _ (UWord w) = UWord w
class GFunctor f where
gmap :: (a -> b) -> f a -> f b
#if __GLASGOW_HASKELL__ >= 701
default gmap :: (Generic1 f, GFunctor' (Rep1 f))
=> (a -> b) -> f a -> f b
gmap = gmapdefault
#endif
gmapdefault :: (Generic1 f, GFunctor' (Rep1 f))
=> (a -> b) -> f a -> f b
gmapdefault f = \xs -> to1 (gmap' f (from1 xs))
-- Base types instances
instance GFunctor ((->) r) where
gmap = fmap
instance GFunctor ((,) a)
instance GFunctor ((,,) a b)
instance GFunctor ((,,,) a b c)
instance GFunctor [] where
gmap = gmapdefault
#if MIN_VERSION_base(4,8,0)
instance GFunctor f => GFunctor (Alt f) where
gmap = gmapdefault
#endif
#if MIN_VERSION_base(4,9,0)
instance GFunctor (Arg a) where
gmap = gmapdefault
#endif
#if MIN_VERSION_base(4,4,0)
instance GFunctor Complex where
gmap = gmapdefault
#endif
instance GFunctor (Const m) where
gmap = gmapdefault
instance GFunctor Down where
gmap = gmapdefault
instance GFunctor Dual where
gmap = gmapdefault
instance GFunctor (Either a) where
gmap = gmapdefault
instance GFunctor Monoid.First where
gmap = gmapdefault
#if MIN_VERSION_base(4,9,0)
instance GFunctor (Semigroup.First) where
gmap = gmapdefault
#endif
#if MIN_VERSION_base(4,8,0)
instance GFunctor Identity where
gmap = gmapdefault
#endif
instance GFunctor IO where
gmap = fmap
instance GFunctor Monoid.Last where
gmap = gmapdefault
#if MIN_VERSION_base(4,9,0)
instance GFunctor Semigroup.Last where
gmap = gmapdefault
instance GFunctor Max where
gmap = gmapdefault
#endif
instance GFunctor Maybe where
gmap = gmapdefault
#if MIN_VERSION_base(4,9,0)
instance GFunctor Min where
gmap = gmapdefault
instance GFunctor NonEmpty where
gmap = gmapdefault
#endif
instance GFunctor Monoid.Product where
gmap = gmapdefault
instance (GFunctor f, GFunctor g) => GFunctor (Functor.Product f g)
instance (GFunctor f, GFunctor g) => GFunctor (Compose f g)
#if MIN_VERSION_base(4,7,0)
instance GFunctor Proxy where
gmap = gmapdefault
#endif
instance GFunctor Monoid.Sum where
gmap = gmapdefault
#if MIN_VERSION_base(4,9,0)
instance (GFunctor f, GFunctor g) => GFunctor (Functor.Sum f g) where
gmap = gmapdefault
instance GFunctor WrappedMonoid where
gmap = gmapdefault
#endif
instance GFunctor ZipList where
gmap = gmapdefault