{-# LANGUAGE CPP, TypeOperators, DataKinds, PolyKinds, TypeFamilies #-} -- | A collection of type-level operators. module Control.Type.Operator ( type (^>), type (<^), type ($), type (&) , type ($$), type (<+>), type (<=>) ) where #if __GLASGOW_HASKELL__ <= 710 import GHC.Prim (Constraint) #else import Data.Kind (Constraint, Type) #endif -- | A tightly binding version of @->@ that lets you strip parentheses from -- function types in certain spots. Example: -- -- @ -- f :: Maybe Int ^> String -- = -- f :: Maybe (Int -> String) -- @ type (^>) = (->) infixr 5 ^> -- | A flipped '^>'. -- -- @ -- f :: Maybe String <^ Int -- = -- f :: Maybe (Int -> String) -- @ -- -- Note: this is not partially applied like '^>' and @->@. type (<^) a b = (^>) b a infixr 5 <^ -- | Infix application. -- -- @ -- f :: Either String $ Maybe Int -- = -- f :: Either String (Maybe Int) -- @ type f $ a = f a infixr 2 $ -- | A flipped '$'. -- -- @ -- f :: Maybe Int & Maybe -- = -- f :: Maybe (Maybe Int) -- @ type a & f = f a infixl 1 & -- | Infix application that can take two arguments in combination with '$'. -- -- @ -- f :: Either $$ Int ^> Int $ Int ^> Int -- = -- f :: Either (Int -> Int) (Int -> Int) -- @ type (f $$ a) = f a infixr 3 $$ {-# DEPRECATED (<=>) "Since (<+>) is now kind-polymorphic and accepts the arguments on either side (<=>) will be removed in a future version." #-} -- | Map a constraint over several variables. -- -- @ -- a :: Show \<=> [a, b] => a -> b -> String -- = -- a :: (Show a, Show b) => a -> b -> String -- @ type family (<=>) (c :: k -> Constraint) (as :: [k]) where (<=>) c '[] = (() :: Constraint) (<=>) c (h ': t) = (c h, (<=>) c t) infixl 9 <=> -- | Map any constraints over any type variables. -- -- @ -- a :: [Show, Read] \<+> a => a -> a -- = -- a :: (Show a, Read a) => a -> a -- -- a :: Show \<+> [a, b, c] => a -> b -> c -> String -- = -- a :: (Show a, Show b, Show c) => a -> b -> c -> String -- @ type family (<+>) (a :: k1) (b :: k2) :: Constraint type instance (<+>) _ [] = (() :: Constraint) type instance (<+>) [] _ = (() :: Constraint) type instance (<+>) (c ': cs) (a :: Type) = (c a, a <+> cs) type instance (<+>) c (a ': as) = (c a, c <+> as) infixl 9 <+>