Haskell-MMorph-Library icon indicating copy to clipboard operation
Haskell-MMorph-Library copied to clipboard

Deriving MFunctor

Open fizruk opened this issue 11 years ago • 5 comments

As far as I can see MFunctor can be derived in a similar way as Functor is derived. I don't have enough TH background yet, so it might take some time if no one would like to make it :)

fizruk avatar Nov 06 '13 15:11 fizruk

I didn't even know that was possible. However, I would prefer this in a separate package (i.e. mfunctor-derive) so that mmorph stays really low on dependencies. Keep in mind that conduit is the major consumer of mmorph and an unexpected dependency on template-haskell might cause problems for conduit.

Gabriella439 avatar Nov 07 '13 19:11 Gabriella439

Also, should I go ahead and upload the generalize code to Hackage, or do you want me to wait for this issue to be resolved first?

Gabriella439 avatar Nov 07 '13 19:11 Gabriella439

This would take a lot of time and indeed in a separate package. So I would prefer generalize on Hackage first :)

fizruk avatar Nov 07 '13 19:11 fizruk

Okay. Just give me a second because I was going through my e-mail and I saw another suggestion for mmorph, which I just created as issue #4. I may want to spend a day or two thinking about that first.

Gabriella439 avatar Nov 07 '13 19:11 Gabriella439

I believe deriving could be implemented similar to this: http://www.mail-archive.com/[email protected]/msg02116.html (also see derive package on hackage, specifically Data.Derive.Functor).

I don't have enough time to learn TH right now, so feel free to implement the idea. As Gabriel noticed this should probably implemented within a separate package, say, mmorph-derive or mfunctor-derive.

Some related stuff:

data T m a = C1 u v w | C2 x y z | ...

instance MFunctor T where
  hoist f t = case t of
      C1 q r s -> C1 (hoist_<a,u> f q) (hoist_<a,v> f r) (hoist_<a,w> f s)
      C2 t u v -> C1 (hoist_<a,x> f t) (hoist_<a,y> f u) (hoist_<a,z> f v)
      ...

-- where

hoist_<m, x> f     = id
hoist_<m, m x> f   = f . fmap (hoist_<m,x> f)
hoist_<m, T x> f   = fmap (hoist_<a,x> f)
hoist_<m, T x y> f = fmap2 (hoist_<a,x> f) . fmap (hoist_<a,y> f)
-- etc.
hoist_<m, x -> y> f = \u -> hoist_<m,y> f . u . contrahoist_<m,x> f

contrahoist_<m, x> f     = id
contrahoist_<m, T x> f   = cofmap (hoist_<m,x> f)
contrahoist_<m, T x y> f = cofmap2 (hoist_<m,x> f) . cofmap (hoist_<m,y> f)
-- etc.
contrahoist_<m, x -> y> f = \u -> contrahoist_<m,y> f . u . hoist_<m,x> f

An example of derivation:

data StateT s m a = StateT (s -> m (a, s))

instance MFunctor (StateT s) where
  hoist f (StateT g) = StateT (hoist_<m,s -> m (a,s)> f g)
    = StateT (hoist_<m,m (a,s)> f . g . contrahoist_<m,s> f)
    = StateT (f . fmap (hoist_<m,(a,s)> f) . g . id)
    = StateT (f . fmap id . g . id)
    = StateT (f . g)

fizruk avatar Nov 12 '13 16:11 fizruk