假设我有这样的功能:
val fooXAB: X => A => Try[B] = ...
val fooXBC: X => B => Try[C] = ...
val fooXCD: X => C => Try[D] = ...
我想将它们组合成一个新功能fooXAD: X => A => Try[D]
,它会依次调用fooXAB
,fooXBC
和fooXCD
并传递{{1}所有这些的参数。
假设我使用X
并拥有scalaz
的monad实例。现在我可以这样做:
scala.util.Try
有意义吗?是否有可能简化它?
答案 0 :(得分:1)
所以我不认为外部功能上的Reader Monad在这里有所帮助。一旦你向你的三个XReader
申请和X,你可以在结果上使用Kleisli
组合(假设你有一个Monad实例用于尝试)。这是你的例子以这种方式重做的,它为我编译:
import scala.util.{Try,Success}
import scalaz._
import Scalaz._
object A
object B
object C
object D
trait X
object Main {
implicit val pretendTryIsAMonad: Monad[Try] = new Monad[Try] {
def point[A](a: => A): Try[A] = Success(a)
def bind[A,B](fa: Try[A])(f: A => Try[B]): Try[B] = fa flatMap f
}
type AB = Kleisli[Try, A.type, B.type]
type BC = Kleisli[Try, B.type, C.type]
type CD = Kleisli[Try, C.type, D.type]
type AD = Kleisli[Try, A.type, D.type]
type XReader[T] = X => T
val fooXAB: XReader[AB] = (x: X) => Kleisli((a: A.type) => Success(B))
val fooXBC: XReader[BC] = (x: X) => Kleisli((b: B.type) => Success(C))
val fooXCD: XReader[CD] = (x: X) => Kleisli((c: C.type) => Success(D))
val fooXAD: XReader[AD] = (x: X) =>
fooXAB(x) >=> fooXBC(x) >=> fooXCD(x)
}