Create ReaderT[F, D, A] from F[A]

Viewed 117
type MapReaderOrOption[A] = ReaderT[Option, Map[String,String], A]

I can create it from ReaderT.apply:

def f:MapReaderOrOption[Int] = ReaderT(_ => Option(10))

From A type via type enrichment and pure method:

import cats.Applicative
import cats.syntax.int._
def f:MapReaderOrOption[Int] = 10.pure[MapReaderOrOption]

I'd like to find something similar. Each time to use ReaderT(..) not so convenient. For sure, I can create a helper method. The question, are there other options?

Expected something like:

def f:MapReaderOrOption[Int] = Option(10).asReaderT[MapReaderOrOption]
2 Answers

Methods that take an F[A] and lift it into an HK[F, A] for some higher-kinded construction HK are consistently called liftF across the library.

In your case, it would be Kleisli.liftF, since ReaderT is just an alias for Kleisli:

import cats.data.ReaderT
import cats.data.Kleisli.liftF

type MapReaderOpt[A] = ReaderT[Option, Map[String, String], A]
val x: MapReaderOpt[Int] = liftF(Option(42))

If liftF seems too vague, you could still rename it into {liftF => liftToReaderT} during a renaming import.

type MapReaderOrOption[A] = ReaderT[Option, Map[String,String], A]

implicit class toReader[F[_],T](f: F[T]) {
  def asReaderT[K] = ReaderT[F,K,T](_ => f)
}

def f:MapReaderOrOption[Int] = Option(10).asReaderT

or in case type of f is not provided explicitly you need to define K parameter.

def f = Option(10).asReaderT[Map[String,String]]

So now type for f will be inferred to ReaderT[Option, Map[String,String], Int]. I think you don't even need type alias in this case.

or one more alternative

def f = Option(10).asReaderT:MapReaderOrOption[Int]
Related