【问题标题】:Either 'orElse' operation on functions returning Eithers and EitherTs对返回 Eithers 和 EitherTs 的函数执行“orElse”操作
【发布时间】:2014-03-23 17:42:56
【问题描述】:

在 Scala/Scalaz 中链接 Either\/ 类型以从左侧的“失败”值中恢复是相当容易的。

除了函数(T1, T2) => Future[A \/ B],如何获得相同的行为?

我已经能够将其分解为两个不同的方向,但无法组合解决方案。

只需利用 Scalaz 的 EitherT 作为 type FutureEither[A, B] = EitherT[Future, A, B]Future 的 monad 实例,就可以轻松链接 Future[A \/ B]

我还可以使用 EitherT 链接 (T1, T2) => A \/ B 类型:

  implicit def wrapTransform[T1, T2, A, B](f: Function2[T1, T2, A \/ B]) = EitherT[({ type λ[α] = Function2[T1, T2, α] })#λ, A, B](f)
  implicit def unwrapTransform[T1, T2, A, B](e: EitherT[({ type λ[α] = Function2[T1, T2, α] })#λ, A, B]): Function2[T1, T2, A \/ B] = e.run

  // some dummy functions
  def times2(fail: Boolean, v: Int): String \/ Int = if (fail) "times2:FAILED".left else (v * 2).right
  def fail(v1: Boolean, v: Int): String \/ Int = "fail:FAILED".left
  def alwaysPlus1(ignore: Boolean, v: Int): String \/ Int =  (v + 1).right

  val times2_times2 = (times2 _) orElse (times2 _)
  val alwaysPlus1_times2 = (alwaysPlus1 _) orElse (times2 _)

  Console println times2_times2(false, 10) // prints '\/-(20)'
  Console println times2_times2(true, 10) // prints '-\/(times2:FAILED)'
  Console println alwaysPlus1_times2(false, 10) // prints '\/-(11)''
  Console println alwaysPlus1_times2(true, 10) // prints '\/-(11)'

您如何编写适用于(T1, T2) => Future[A \/ B] 类型的两级嵌套的转换器?

我的函数式编程知识仍在学习中,因此对于措辞和术语使用不当,我深表歉意。

【问题讨论】:

    标签: scala functional-programming monads scalaz


    【解决方案1】:

    如果你有例如Option 而不是 Future,您可以向堆栈添加一个层:

    def wrap[T1, T2, A, B](f: (T1, T2) => Option[A \/ B]) = EitherT[
      ({ type L1[a] = OptionT[
        ({ type L2[b] = (T1, T2) => b })#L2, a
      ] })#L1, A, B
    ](OptionT[({ type L2[b] = (T1, T2) => b })#L2, A \/ B](f))
    

    这是一团糟,但您可以相当机械地填写类型,因为您只是从内向外移动 - 例如我们的(T1, T2) => Option[A \/ _] 变成了EitherT[OptionT[(T1, T2) => _, _], A, _]

    问题是,如果你想用Future 来做这件事,你需要FutureT,而共识是因为它是not possible to write FutureT without blockingit's better not to provide it

    【讨论】:

      猜你喜欢
      • 2013-12-23
      • 1970-01-01
      • 1970-01-01
      • 2018-02-11
      • 1970-01-01
      • 2018-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多