module Data.StarToStar.Contra where
import qualified Data.StarToStar as DS
import Control.Arrow ((***))
import Control.Functor.Contra
instance Cofunctor DS.V where cofmap _ = undefined
instance Cofunctor DS.U where cofmap _ DS.U = DS.U
instance Cofunctor (DS.C b) where cofmap _ = DS.onC DS.toC
instance Cofunctor (DS.K r) where cofmap f = DS.toK . DS.onK (. f)
instance (Functor f, Cofunctor g) => Cofunctor (DS.O f g) where
cofmap = DS.underO . fmap . cofmap
newtype O f g a = O (f (g a))
instance (Cofunctor f, Cofunctor g) => Functor (O f g) where
fmap = underO . cofmap . cofmap
instance (Cofunctor f, Functor g) => Cofunctor (O f g) where
cofmap = underO . cofmap . fmap
onO :: (f (g a) -> b) -> O f g a -> b
onO f (O x) = f x
underO :: (f (g a) -> h (i b)) -> O f g a -> O h i b
underO f = toO . onO f
toO :: f (g a) -> O f g a
toO x = O x
fromO :: O f g a -> f (g a)
fromO x = onO id x
instance (Cofunctor f, Cofunctor g) => Cofunctor (DS.S f g) where
cofmap f = DS.onS' (DS.L . cofmap f) (DS.R . cofmap f)
instance (Cofunctor f, Cofunctor g) => Cofunctor (DS.P f g) where
cofmap f = DS.underP (cofmap f *** cofmap f)
instance (Cofunctor f, Functor g) => Functor (DS.F f g) where
fmap f = DS.underF ((fmap f .) . (. cofmap f))
instance (Functor f, Cofunctor g) => Cofunctor (DS.F f g) where
cofmap f = DS.underF ((cofmap f .) . (. fmap f))
instance Cofunctor (ff (DS.Fix ff)) => Cofunctor (DS.Fix ff) where
cofmap = DS.underFix . cofmap