@@ -1,4 +1,5 @@
1−{-# LANGUAGE Rank2Types #-}
1+{-# LANGUAGE GADTs #-}
2+{-# LANGUAGE Rank2Types #-}
23{-# LANGUAGE TypeOperators #-}
34
45-----------------------------------------------------------------------------
@@ -89,3 +90,20 @@ _Left = prism Left $ either Right (Left . Right)
8990
9091_Right :: Prism' (Either c a) a
9192_Right = prism Right $ either (Left . Left) Right
93+
94+--------------------------------------------------------------------------------
95+
96+data Coyoneda f b = forall a. Coyoneda (a -> b) (f a)
97+
98+instance Functor (Coyoneda f) where
99+ fmap f (Coyoneda g fa)
100+ = Coyoneda (f . g) fa
101+
102+inj :: Functor f => Coyoneda f a -> f a
103+inj (Coyoneda f a) = fmap f a
104+
105+proj :: Functor f => f a -> Coyoneda f a
106+proj fa = Coyoneda id fa
107+
108+ravel :: Functor f => ((a -> Coyoneda f b) -> s -> Coyoneda f t) -> (a -> f b) -> (s -> f t)
109+ravel coy f s = inj $ coy (\a -> proj (f a)) s