## 动力学知识库

Suppose I have functions like this:

``val fooXAB: X => A => Try[B] = ...val fooXBC: X => B => Try[C] = ...val fooXCD: X => C => Try[D] = ...``

I'd like to compose them to make a new function `fooXAD: X => A => Try[D]`, which calls `fooXAB`, `fooXBC`, and `fooXCD` sequentially and pass the `X` argument to all of them.

Suppose I use `scalaz` and have a monad instance for `scala.util.Try`. Now I can do it this way:

``type AB = Kleisli[Try, A, B]type BC = Kleilsi[Try, B, C]type CD = Kleisli[Try, C, D]type XReader[T] = Reader[X, T]val fooXAB: XReader[AB] = ...val fooXBC: XReader[BC] = ...val fooXCD: XReader[CD] = ...val fooXAC: XReader[AC] =for {ab <- fooXABbc <- fooXBCcd <- fooXCD} yield (ab andThen bc andThen cd)``

Does it make sense? Is it possible to simplify it ?

So I don't think the Reader Monad on the outer function helps here. once you apply and X to your threee `XReader`s, you can use `Kleisli` composition on the results (assuming you have a Monad instance for Try). Here's your example reworked this way, and it compiles for me:

``````import scala.util.{Try,Success}

import scalaz._
import Scalaz._

object A
object B
object C
object D
trait X

object Main {
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))