functor-monad-0.1.1.0: src/Data/Functor/Precompose.hs
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TypeOperators #-}
module Data.Functor.Precompose where
import Data.Kind (Type)
import Control.Applicative (Alternative)
import Control.Monad (join)
import Control.Comonad(Comonad(..))
import Data.Functor.Classes (Eq1, Ord1)
import Data.Functor.Compose ( Compose(..) )
import FMonad
import FComonad
-- | Single-kinded type alias of Compose
type (:.:) :: (Type -> Type) -> (Type -> Type) -> Type -> Type
type (:.:) = Compose
-- | Flipped-order Compose.
--
-- When @f@ is a @Monad@, @Precompose f@ is a 'FMonad' in the similar way 'Compose' is.
--
-- The only difference is @Precompose f@ composes @f@ to the right (_pre_compose)
-- compared to @Compose f@ which composes to the left (_post_compose).
type Precompose :: (j -> k) -> (k -> Type) -> j -> Type
newtype Precompose f g a = Precompose {getPrecompose :: g (f a)}
deriving stock (Show, Read, Functor, Foldable)
deriving stock instance (Traversable f, Traversable g) => Traversable (Precompose f g)
deriving via
((g :.: f) a)
instance
(Eq1 f, Eq1 g, Eq a) => Eq (Precompose f g a)
deriving via
((g :.: f) a)
instance
(Ord1 f, Ord1 g, Ord a) => Ord (Precompose f g a)
deriving via
(g :.: f)
instance
(Eq1 f, Eq1 g) => Eq1 (Precompose f g)
deriving via
(g :.: f)
instance
(Ord1 f, Ord1 g) => Ord1 (Precompose f g)
deriving via
(g :.: f)
instance
(Applicative f, Applicative g) => Applicative (Precompose f g)
deriving via
(g :.: f)
instance
(Applicative f, Alternative g) => Alternative (Precompose f g)
instance Functor f => FFunctor (Precompose f) where
ffmap gh = Precompose . gh . getPrecompose
instance Monad f => FMonad (Precompose f) where
fpure = Precompose . fmap return
fbind k = Precompose . fmap join . getPrecompose . k . getPrecompose
instance Comonad f => FComonad (Precompose f) where
fextract = fmap extract . getPrecompose
fextend tr = Precompose . tr . Precompose . fmap duplicate . getPrecompose