Gabriella439 / Haskell-MMorph-Library

Monad morphisms
BSD 3-Clause "New" or "Revised" License
47 stars 26 forks source link

MInvFunctor #48

Closed xgrommx closed 5 years ago

xgrommx commented 5 years ago

Hello @Gabriel439. Some structure cannot to have instance for MFunctor. For example it will be ContT, Codensity and etc. But we can create some invariant version of MFunctor

hoistLogicT :: (f ~> g) -> (g ~> f) -> (LogicT f ~> LogicT g)
hoistLogicT nat1 nat2 (LogicT ma) = LogicT (\k mr -> nat1 (ma (\x y -> nat2 (k x (nat1 y))) (nat2 mr)))

hoistContT :: (f ~> g) -> (g ~> f) -> (ContT r f ~> ContT r g)
hoistContT nat1 nat2 (ContT m) = ContT (\k -> nat1 (m (nat2 <<< k)))

hoistCodensity :: (f ~> g) -> (g ~> f) -> Codensity f ~> Codensity g
hoistCodensity nat1 nat2 (Codensity m) = Codensity (\k -> nat1 (m (nat2 <<< k)))

class MInvFunctor t where
  invHoist :: forall m n. Monad m => (m ~> n) -> (n ~> m) -> t m ~> t n

instance MInvFunctor Codensity where
  invHoist = hoistCodensity

instance MInvFunctor (ContT r) where
  invHoist = hoistContT

instance MInvFunctor LogicT where
  invHoist = hoistLogicT

What do u think about it?

xgrommx commented 5 years ago

Also I have question why in MFunctor we use restriction like Monad m and not Monad n?

Gabriella439 commented 5 years ago

@xgrommx: The main reason I haven't yet added higher-kinded invariant functors is because they tend to only be used for Cont-like monads

The reason for the Monad n constraint is because this library originated with pipes and conduit as the initial users and they both required a Monad n constraint at the time

duairc commented 5 years ago

This is a duplicate of #1 ;)

Gabriella439 commented 5 years ago

@duairc: Yeah, you're right! 🙂

I can go ahead and close this, then, as a duplicate