content: {-# LANGUAGE ExplicitNamespaces, PolyKinds, KindSignatures, MultiParamTypeClasses, FunctionalDependencies, TypeFamilies, TypeOperators, NoImplicitPrelude #-}
  module Hask.Adjunction
    ( type (-|)(..)
    , swap
    -- , Curried(..)
    ) where
  
  import Hask.Category
  import Hask.Iso
  
  --------------------------------------------------------------------------------
  -- * Adjunctions
  --------------------------------------------------------------------------------
  
  class (Functor f, Functor g, Dom f ~ Cod g, Cod g ~ Dom f) => (f :: j -> i) -| (g :: i -> j) | f -> g, g -> f where
    adj :: Iso (->) (->) (->) (Cod f (f a) b) (Cod f (f a') b') (Cod g a (g b)) (Cod g a' (g b'))
  
  -- instance (,) e -| (->) e where
  --   adj = dimap (. swap) (. swap) . curried
  
  swap :: (a,b) -> (b,a)
  swap (a,b) = (b,a)
  
  --------------------------------------------------------------------------------
  -- * Currying
  --------------------------------------------------------------------------------
  
  -- class (Bifunctor p, Bifunctor q) => Curried (p :: k -> i -> j) (q :: i -> j -> k) | p -> q, q -> p where
  --   curried :: Iso (->) (->) (->)
  --     (Dom2 p (p a b) c) (Dom2 p (p a' b') c')
  --     (Dom2 q a (q b c)) (Dom2 q a' (q b' c'))
  
  -- instance Curried (,) (->) where
  --   curried = dimap Prelude.curry Prelude.uncurry
  