0

I've created a function which is polymorphic in the Monad it needs to use, instead it depends on the typeclass instances that exists for this Monad. It looks like this:

fun <M> M.logic(...): Kind<M, String>
      where M: MonadReader<M, Dependency>,
            M: Effect<M> =
   fx.monad() {
      val dependency = ask().bind()
      val response = effect { ...using dependency here... }.bind()
      response
   }

I'm using the MonadReader to get a dependency, and I'm using Effect, well, for effects. Now I assumed, that all I need is to use some Monad Transformers to get to this constellation of a Monad "at the end of the world" (i.e. in main()). Something like ReaderT<ForIO, Dependency, Unit>.

However, I can't seem to create a suitable M (or any context) to call this method on. How can I call this method on an exact monad that has the necessary typeclass instances?

Robert Bräutigam
  • 7,514
  • 1
  • 20
  • 38

1 Answers1

1

This is the code snippet you're after:

fun <M, F> M.logic(): Kind<F, String>
  where M: MonadReader<F, String>,
        M: Async<F> =
  fx.monad {
    val dependency = ask().bind()
    val response = effect { dependency }.bind()
    response
  }

object Transformer: 
  Async<KleisliPartialOf<ForIO, String>> by ReaderT.async(IO.effect()),
  KleisliMonadReader<ForIO, String> by ReaderT.monadReader(IO.monad())

Note that Async is what you're after, not the poorly named Effect. And you need two generics, one for the composition and another for the content.

Transformer.run {
  logic()
}

The Async instance for Reader was added on January 2020, and will be available on the next release, either 0.10.5 or 0.11.0: https://github.com/arrow-kt/arrow/commit/6aaae6998de612eb0eec948697f1c477649230be

El Paco
  • 546
  • 2
  • 6
  • 1
    Thanks, I compiled the 0.10.5-SNAPSHOT and it provides the instance for the code you provided. Unfortunately both delegates of the `Transformer` now implement the basic stuff, like applicative/functor/etc. This means I would have to explicitly override those (many dozens of) methods and delegate them manually. All in all, I think it may not be worth the effort :) – Robert Bräutigam Feb 08 '20 at 20:45
  • Many dozens? I would have thought it was just a couple, the ones that are not default implementations. – El Paco Feb 09 '20 at 12:54