After Mathew's suggestion (thanks !!), I've been able to finish all the code:

{-# LANGUAGE MultiParamTypeClasses #-}

{-# LANGUAGE FunctionalDependencies #-}

{-# LANGUAGE Rank2Types #-}

{-# LANGUAGE TypeOperators #-}

{-# LANGUAGE KindSignatures #-}

{-# LANGUAGE PolyKinds #-}

{-# LANGUAGE DeriveFunctor #-}

module Adjunction where

import Control.Monad

class (Functor f, Functor g) => Adjunction f g | f -> g, g -> f where

{-# MINIMAL (unit, counit) | (leftAdjunct, rightAdjunct) #-}

-- leftAdjunct . rightAdjunct === id

-- rightAdjunct . leftAdjunct === id

leftAdjunct :: (f a -> b) -> a -> g b

leftAdjunct f = fmap f . unit

rightAdjunct :: (a -> g b) -> f a -> b

rightAdjunct f = counit . fmap f

-- leftAdjunct counit === id

-- rightAdjunct unit === id

unit :: a -> g (f a)

unit = leftAdjunct id

counit :: f (g a) -> a

counit = rightAdjunct id

instance Adjunction ((,) e) ((->) e) where

-- leftAdjunct :: ((e, a) -> b) -> a -> e -> b

-- rightAdjunct :: (a -> e -> b) -> (e, a) -> b

leftAdjunct f a e = f (e,a)

rightAdjunct f (e,a) = f a e

infixr 7 :.:

newtype (:.:) (f :: k2 -> *) (g :: k1 -> k2) (p :: k1) = Comp1 { unComp1 :: f (g p) }

deriving (Functor)

instance Adjunction f g => Applicative (g :.: f) where

pure = return

(<*>) = ap

instance Adjunction f g => Monad (g :.: f) where

return = Comp1 . unit

x >>= f = Comp1 (fmap (rightAdjunct (unComp1 . f)) (unComp1 x))

{-# LANGUAGE MultiParamTypeClasses #-}

{-# LANGUAGE FunctionalDependencies #-}

{-# LANGUAGE Rank2Types #-}

{-# LANGUAGE TypeOperators #-}

{-# LANGUAGE KindSignatures #-}

{-# LANGUAGE PolyKinds #-}

{-# LANGUAGE DeriveFunctor #-}

module Adjunction where

import Control.Monad

class (Functor f, Functor g) => Adjunction f g | f -> g, g -> f where

{-# MINIMAL (unit, counit) | (leftAdjunct, rightAdjunct) #-}

-- leftAdjunct . rightAdjunct === id

-- rightAdjunct . leftAdjunct === id

leftAdjunct :: (f a -> b) -> a -> g b

leftAdjunct f = fmap f . unit

rightAdjunct :: (a -> g b) -> f a -> b

rightAdjunct f = counit . fmap f

-- leftAdjunct counit === id

-- rightAdjunct unit === id

unit :: a -> g (f a)

unit = leftAdjunct id

counit :: f (g a) -> a

counit = rightAdjunct id

instance Adjunction ((,) e) ((->) e) where

-- leftAdjunct :: ((e, a) -> b) -> a -> e -> b

-- rightAdjunct :: (a -> e -> b) -> (e, a) -> b

leftAdjunct f a e = f (e,a)

rightAdjunct f (e,a) = f a e

infixr 7 :.:

newtype (:.:) (f :: k2 -> *) (g :: k1 -> k2) (p :: k1) = Comp1 { unComp1 :: f (g p) }

deriving (Functor)

instance Adjunction f g => Applicative (g :.: f) where

pure = return

(<*>) = ap

instance Adjunction f g => Monad (g :.: f) where

return = Comp1 . unit

x >>= f = Comp1 (fmap (rightAdjunct (unComp1 . f)) (unComp1 x))