Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MFunctor type class for mapping monad morphisms over monad transformers #1492

Closed
wants to merge 2 commits into from

Conversation

kcsongor
Copy link
Contributor

@kcsongor kcsongor commented Dec 10, 2016

WIP:

This generalises the notion of changing the underlying monad of a monad transformer using a natural transformation.

I opened the PR to have some feedback/discussion on the following points:

  • Currently the natural transformation is not constrained to be a monad morphism, but I feel like it should be (or a constraint parameter?)
  • No syntax yet, I'm not sure what's the best way to do this
  • No laws yet - these are the same as the functor laws
  • No examples

@codecov-io
Copy link

codecov-io commented Dec 10, 2016

Current coverage is 91.63% (diff: 0.00%)

Merging #1492 into master will decrease coverage by 0.30%

@@             master      #1492   diff @@
==========================================
  Files           244        244          
  Lines          3621       3633    +12   
  Methods        3502       3513    +11   
  Messages          0          0          
  Branches        119        120     +1   
==========================================
  Hits           3329       3329          
- Misses          292        304    +12   
  Partials          0          0          

Powered by Codecov. Last update 73a6481...f06e4c2

@edmundnoble
Copy link
Contributor

As coded, this is also known as Functor1 and FunctorK. I believe this captures the notion of a Functor transformer, (or Functor in the category of Functors) which includes Comonad transformers, so I think it deserves its own place in cats even if a version of it is specialized to Monads and possibly Comonads. I believe constrained natural transformations may provide a basis for what you want in terms of constraints, but otherwise you might want to perhaps look at Ed Kmett's version of MonadTrans for some inspiration.

@kcsongor
Copy link
Contributor Author

@edmundnoble thanks for your comments, I agree that without codifying the constraints, it really is more general than my original description of the type class - that is that it's a functor in the category of monads, rather it's a functor in the category of endofunctors of scala types, if we view all (* -> *) kinded types as functors.
But I think this is more general than transformers? The free monad also has a valid instance, whereby it's possible to lift a natural transformation to get a monad homomorphism between the free monads of the domain and codomain of the natural transformation respectively. (Perhaps this is what you meant by a functor transformer?)

I'm just not sure how far this generalisation should be taken, what do you think? I'm now tempted to just leave it as it is, and introduce a constraint member to the class, which then makes it possible to write out all instances of interest (monad transformers, comonad transformers, free monads, etc)

@edmundnoble
Copy link
Contributor

edmundnoble commented Dec 11, 2016

Yoneda, Coyoneda, Density, Codensity, FreeMonad, FreeAp and most other examples of Kan extensions seem to amount to one of these functors on functors, or functor transformers. Yes, that's all I meant by functor transformer: just a functor on functors. I believe adding a separate class with a constraint member might be nicer, just because the parametric ones that don't care about the constraint have an interesting place too. Unless we'd like to standardize on a Trivial constraint.

@xuwei-k
Copy link
Contributor

xuwei-k commented Dec 14, 2016

@kcsongor
Copy link
Contributor Author

@xuwei-k thanks for linking those in, the mmorph library is indeed where I picked up the name from, although I am planning to take a somewhat different direction here

@kailuowang
Copy link
Contributor

There are two shapes of this possible transformation type class, discussed here.
https://gist.github.com/kailuowang/ddf4f99a3bd97f150277a0c614e0a6f2#gistcomment-2091135
There is a plan to implement the trait TFunctor[T[_[_], _]] in cats-mtl, @edmundnoble, is that still the plan?
I implemented the trait MFunctor[T[_[_]]shape in mainecoon with laws, but mainly for the purpose of transforming final tagless interpreters.
For transforming between monad transformers, trait TFunctor[T[_[_], _]] seems a better fit, and cats-mtl seems a better place for it to live.

@edmundnoble
Copy link
Contributor

@kailuowang This is no longer planned to be included in cats-mtl. I don't see a use for it, but I'd be interested in hearing of one. As is we'd need three variants, for mapping natural transformations, applicative homomorphisms, and monad homomorphisms.

@kailuowang
Copy link
Contributor

related #1713
@edmundnoble is there use case for applicative homomorphisms and monad homomorphisms, in cats core? I am thinking we should add mapping natural transformations, i.e. TFunctor[F[_[_], _] in cats.core in RC1. Not sure about the other two.

@kailuowang kailuowang added this to the 1.0.0-RC1 milestone Aug 9, 2017
@edmundnoble
Copy link
Contributor

What is the usecase of mapping natural transformations though?

@kailuowang
Copy link
Contributor

@edmundnoble, as mentioned in this ticket, one use case is to abstract out "changing the underlying monad of a monad transformer using a natural transformation."
Such need is also raised in here.

@edmundnoble
Copy link
Contributor

Right, I'm asking for a concrete instantiation of such a use case. I don't think such a thing is useful generically; though it's useful for specific monad transformers, inductive usage cannot actually change the monad inside a transformer.

@kailuowang
Copy link
Contributor

I realized that myself after I wrote #1812. The only immediate benefit seems to be the conformity of the API. It creates a consistent way mapNT to do such inner monad swap. In the long run, it proves that these things (see the instances in #1812) are indeed endofunctors in the category of endofunctors. Maybe someone will discover generic usage of it in the future? Like we didnt know the FunctorK is useful until we discovered final tagless encoding. Of course such speculation isn't a good reason to add it now to cats.core, but the API conformity might be.

@kailuowang kailuowang mentioned this pull request Aug 11, 2017
@kailuowang
Copy link
Contributor

continued on #1815, closing for now.

@kailuowang kailuowang closed this Aug 29, 2017
@kailuowang kailuowang removed this from the 1.0.0-RC1 milestone Oct 13, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants