Создать ReaderT [F, D, A] из F [A] - PullRequest
3 голосов
/ 07 июня 2019
type MapReaderOrOption[A] = ReaderT[Option, Map[String,String], A]

Я могу создать его из ReaderT.apply:

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

Из типа А через обогащение типа и чистый метод:

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

Я бы хотел найти что-то похожее. Каждый раз использовать ReaderT (..) не так удобно. Конечно, я могу создать вспомогательный метод. Вопрос, есть ли другие варианты?

Ожидается что-то вроде:

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

Ответы [ 2 ]

7 голосов
/ 07 июня 2019

Методы, которые берут 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} во время переименования импорта.

6 голосов
/ 07 июня 2019
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]
...