从F [A]创建ReaderT [F,D,A]

时间:2019-06-07 11:27:45

标签: scala scala-cats reader-monad

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

我可以从ReaderT.apply创建它:

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

通过类型丰富和纯方法从A类型中获取

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

我想找到类似的东西。每次使用ReaderT(..)都不那么方便。当然,我可以创建一个辅助方法。问题是,还有其他选择吗?

预期如下:

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

2 个答案:

答案 0 :(得分:7)

采用F[A]并将其提升到HK[F, A]以进行某些更高类型的构造HK的方法在整个库中始终称为liftF

在您的情况下,它将是Kleisli.liftF,因为ReaderT只是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))

如果liftF过于模糊,您仍可以在重命名导入期间将其重命名为{liftF => liftToReaderT}

答案 1 :(得分:6)

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

或者在未明确提供f类型的情况下,您需要定义K参数。

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

因此,现在将f的类型推断为ReaderT[Option, Map[String,String], Int]。我认为您在这种情况下甚至不需要类型别名。

或另外一种选择

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