Предположим, у меня есть две монады F
и M
(в стиле Скалаз) и функция f: A => F[B]
. Я хотел бы создать функцию g: A => F[M[B]]
, которая сначала применяет f, а затем связывает F-монаду с pure[M]
. Пример для наглядности:Преобразование монадической функции для возврата точки в другой монаде
// here, F = Option and M = List
import scalaz.syntax.monad._
import scalaz.std.list._
def f(x: Int): Option[Int] = Some(x)
def g(x: Int): Option[List[Int]] = f(x).map(t => List(t))
Здесь, реализация g
использует внутреннюю монаду (List
) конструктор явно. Я мог бы избежать этого следующим образом:
def g2[M[_]: Monad](x: Int): Option[M[Int]] = f(x).map(_.pure[M])
Теперь вопрос: У меня есть функция, которая ожидает что-то вроде g
(так функция стоимости Int => Option[List[Int]]
) и что-то вроде f
в моих руках. Как я могу кормить друг друга? Проще говоря:
def f(x: Int): Option[Int] = ...
def callMe(h: (Int => Option[List[Int]]) = ...
//I can of course do that:
callMe(t => f(t).map(_.point[List]))
//How it without lambda expression?
callMe(f.kindOfALift[List]???)
callMe(f andThen ???)
Проблема здесь может быть, конечно, отведенной для поддержки не только Int => Option[Int]
но A => M[B]
в целом, но это легкая часть. Жесткая часть (для меня) обертывает результат во внутреннюю монаду. Следующий шаг - заставить его работать над преобразованными монадами (поэтому вместо того, чтобы иметь монаду M
, будет здорово заставить его работать с трансформатором monad MT
). Любые намеки?
Я использую scalaz как мешок полезных ярлыков, поэтому я надеялся на то, что не нуждается в моих неявных классах ... 'f.andThen (_. Map (_. Point))' работает, конечно, но было бы здорово избежать лишних '_.map' –