content: {-# LANGUAGE
      DataKinds,
      PolyKinds,
      TypeFamilies,
      TypeOperators #-}
  
  -- | Common data types: tuples, 'Either', 'Maybe'.
  module Fcf.Data.Common
    ( -- ** Pairs
      Uncurry
    , Fst
    , Snd
    , type (***)
  
      -- ** Either
    , UnEither
    , IsLeft
    , IsRight
  
      -- ** Maybe
    , UnMaybe
    , FromMaybe
    , IsNothing
    , IsJust
    ) where
  
  import Fcf.Core
  
  -- ** Pairs
  
  data Uncurry :: (a -> b -> Exp c) -> (a, b) -> Exp c
  type instance Eval (Uncurry f '(x, y)) = Eval (f x y)
  
  data Fst :: (a, b) -> Exp a
  type instance Eval (Fst '(a, _b)) = a
  
  data Snd :: (a, b) -> Exp b
  type instance Eval (Snd '(_a, b)) = b
  
  
  infixr 3 ***
  
  -- | Specialization of 'Fcf.Class.Bifunctor.Bimap' for pairs.
  data (***) :: (b -> Exp c) -> (b' -> Exp c') -> (b, b') -> Exp (c, c')
  type instance Eval ((***) f f' '(b, b')) = '(Eval (f b), Eval (f' b'))
  
  
  -- ** Either
  
  data UnEither :: (a -> Exp c) -> (b -> Exp c) -> Either a b -> Exp c
  type instance Eval (UnEither f g ('Left  x)) = Eval (f x)
  type instance Eval (UnEither f g ('Right y)) = Eval (g y)
  
  data IsLeft :: Either a b -> Exp Bool
  type instance Eval (IsLeft ('Left _a)) = 'True
  type instance Eval (IsLeft ('Right _a)) = 'False
  
  data IsRight :: Either a b -> Exp Bool
  type instance Eval (IsRight ('Left _a)) = 'False
  type instance Eval (IsRight ('Right _a)) = 'True
  
  
  -- ** Maybe
  
  data UnMaybe :: Exp b -> (a -> Exp b) -> Maybe a -> Exp b
  type instance Eval (UnMaybe y f 'Nothing) = Eval y
  type instance Eval (UnMaybe y f ('Just x)) = Eval (f x)
  
  data FromMaybe :: k -> Maybe k -> Exp k
  type instance Eval (FromMaybe a 'Nothing)   = a
  type instance Eval (FromMaybe _a ('Just b)) = b
  
  data IsNothing :: Maybe a -> Exp Bool
  type instance Eval (IsNothing ('Just _a)) = 'False
  type instance Eval (IsNothing 'Nothing) = 'True
  
  data IsJust :: Maybe a -> Exp Bool
  type instance Eval (IsJust ('Just _a)) = 'True
  type instance Eval (IsJust 'Nothing) = 'False
  