{-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE Rank2Types #-} {-# LANGUAGE TypeOperators #-} module Test.StateMachine.Types.Rank2 ( Functor , fmap , gfmap , (<$>) , Foldable , foldMap , gfoldMap , Traversable , traverse , gtraverse ) where import qualified Control.Applicative as Rank1 import qualified Control.Monad as Rank1 import qualified Data.Foldable as Rank1 import Data.Kind (Type) import qualified Data.Traversable as Rank1 import GHC.Generics ((:*:)((:*:)), (:+:)(L1, R1), Generic1, K1(K1), M1(M1), Rec1(Rec1), Rep1, U1(U1), from1, to1, (:.:)(Comp1)) import Prelude hiding (Applicative(..), Foldable(..), Functor(..), Traversable(..), (<$>)) ------------------------------------------------------------------------ class Functor (f :: (k -> Type) -> Type) where fmap :: (forall x. p x -> q x) -> f p -> f q default fmap :: (Generic1 f, Functor (Rep1 f)) => (forall x. p x -> q x) -> f p -> f q fmap = gfmap gfmap :: (Generic1 f, Functor (Rep1 f)) => (forall a. p a -> q a) -> f p -> f q gfmap f = to1 . fmap f . from1 (<$>) :: Functor f => (forall x. p x -> q x) -> f p -> f q (<$>) = fmap {-# INLINE (<$>) #-} instance Functor U1 where fmap _ U1 = U1 instance Functor (K1 i c) where fmap _ (K1 c) = K1 c instance (Functor f, Functor g) => Functor (f :+: g) where fmap f (L1 x) = L1 (fmap f x) fmap f (R1 y) = R1 (fmap f y) instance (Functor f, Functor g) => Functor (f :*: g) where fmap f (x :*: y) = fmap f x :*: fmap f y instance (Rank1.Functor f, Functor g) => Functor (f :.: g) where fmap f (Comp1 fg) = Comp1 (Rank1.fmap (fmap f) fg) instance Functor f => Functor (M1 i c f) where fmap f (M1 x) = M1 (fmap f x) instance Functor f => Functor (Rec1 f) where fmap f (Rec1 x) = Rec1 (fmap f x) ------------------------------------------------------------------------ class Foldable (f :: (k -> Type) -> Type) where foldMap :: Monoid m => (forall x. p x -> m) -> f p -> m default foldMap :: (Generic1 f, Foldable (Rep1 f), Monoid m) => (forall a. p a -> m) -> f p -> m foldMap = gfoldMap gfoldMap :: (Generic1 f, Foldable (Rep1 f), Monoid m) => (forall a. p a -> m) -> f p -> m gfoldMap f = foldMap f . from1 instance Foldable U1 where foldMap _ U1 = mempty instance Foldable (K1 i c) where foldMap _ (K1 _) = mempty instance (Foldable f, Foldable g) => Foldable (f :+: g) where foldMap f (L1 x) = foldMap f x foldMap f (R1 y) = foldMap f y instance (Foldable f, Foldable g) => Foldable (f :*: g) where foldMap f (x :*: y) = foldMap f x `mappend` foldMap f y instance (Rank1.Foldable f, Foldable g) => Foldable (f :.: g) where foldMap f (Comp1 fg) = Rank1.foldMap (foldMap f) fg instance Foldable f => Foldable (M1 i c f) where foldMap f (M1 x) = foldMap f x instance Foldable f => Foldable (Rec1 f) where foldMap f (Rec1 x) = foldMap f x ------------------------------------------------------------------------ class (Functor t, Foldable t) => Traversable (t :: (k -> Type) -> Type) where traverse :: Rank1.Applicative f => (forall a. p a -> f (q a)) -> t p -> f (t q) default traverse :: (Generic1 t, Traversable (Rep1 t), Rank1.Applicative f) => (forall a. p a -> f (q a)) -> t p -> f (t q) traverse = gtraverse gtraverse :: (Generic1 t, Traversable (Rep1 t), Rank1.Applicative f) => (forall a. p a -> f (q a)) -> t p -> f (t q) gtraverse f = Rank1.fmap to1 . traverse f . from1 instance Traversable U1 where traverse _ U1 = Rank1.pure U1 instance Traversable (K1 i c) where traverse _ (K1 c) = Rank1.pure (K1 c) instance (Traversable f, Traversable g) => Traversable (f :+: g) where traverse f (L1 x) = L1 Rank1.<$> traverse f x traverse f (R1 y) = R1 Rank1.<$> traverse f y instance (Traversable f, Traversable g) => Traversable (f :*: g) where traverse f (x :*: y) = (:*:) Rank1.<$> traverse f x Rank1.<*> traverse f y instance (Rank1.Traversable f, Traversable g) => Traversable (f :.: g) where traverse f (Comp1 fg) = Comp1 Rank1.<$> Rank1.traverse (traverse f) fg instance Traversable f => Traversable (M1 i c f) where traverse f (M1 x) = M1 Rank1.<$> traverse f x instance Traversable f => Traversable (Rec1 f) where traverse f (Rec1 x) = Rec1 Rank1.<$> traverse f x