yoko-0.2: Type/Yoko/Natural.hs
{-# LANGUAGE ExistentialQuantification, QuasiQuotes, TypeOperators,
Rank2Types, GADTs, ScopedTypeVariables, TypeFamilies #-}
{- |
Module : Type.Yoko.Natural
Copyright : (c) The University of Kansas 2011
License : BSD3
Maintainer : nicolas.frisby@gmail.com
Stability : experimental
Portability : see LANGUAGE pragmas (... GHC)
Natural transformations and pairs.
-}
module Type.Yoko.Natural where
import Type.Yoko.Type
import Type.Yoko.Universe
type NT_ u f = forall t. u t -> f t
-- | Natural transformations. We use 'Unwrap' to lighten the user interface at
-- the value level, though it clutters the types a little.
newtype NT u f = NT (forall t. u t -> Unwrap f t)
nt_ :: [qP|f :: *->*|] -> (forall t. u t -> Unwrap f t) -> NT u f
nt_ p f = NT f
appNT :: NT u f -> u t -> Unwrap f t
appNT (NT f) x = f x
appNTF :: Wrapper f => NT u f -> NT_ u f
appNTF (NT f) x = wrap (f x)
-- | Defining an @NT@ via type-level backtracking; ':||' uses 'Pred' to
-- short-circuit, preferring inhabitation of @u@ over @v@.
orNT :: NT u f -> NT v f -> NT (u :|| v) f
orNT (NT f) (NT g) = NT $ \uv -> case uv of
LeftU u -> f u
RightU v -> g v
constNT :: Unwrap f t -> NT ((:=:) t) f
constNT = constNT_ Proxy
constNT_ :: [qP|f :: *->*|] -> Unwrap f t -> NT ((:=:) t) f
constNT_ p x = nt_ p $ \Refl -> x
constNTF :: Wrapper f => f t -> NT ((:=:) t) f
constNTF x = NT $ \Refl -> unwrap x
firstNT :: NT_ u g -> NT g f -> NT u f
firstNT g (NT f) = NT $ f . g
-- | Natural pairs.
data NP u f = forall t. NP (u t) (Unwrap f t)
-- | Analog to "Control.Arrow"@.first@.
firstNP :: NT_ u v -> NP u f -> NP v f
firstNP f (NP u x) = NP (f u) x
-- | @ArrowTSS@ can be partially applied, and hence occur as the second
-- argument of @NT@, where as @f _ -> g _@ cannot.
newtype ArrowTSS f g a = ArrowTSS (f a -> g a)
type instance Unwrap (ArrowTSS f g) a = f a -> g a
instance Wrapper (ArrowTSS f g) where wrap = ArrowTSS; unwrap (ArrowTSS f) = f
appNTtoNP :: (Wrapper f, Wrapper g) => NT u (ArrowTSS f g) -> NP u f -> NP u g
appNTtoNP (NT f) (NP u x) = NP u $ unwrap $ f u $ wrap x