4

在 Scala 中,我可以拥有:

trait Api {
    def someApiCall: Either[Failure, GoodResult];
}

或者

object SomeObject {
    type SomeResult = Either[Failure, GoodResult]
}

trait Api {
    def someApiCall: SomeObject.SomeResult;
}

前者对结果类型更明确,因此更易于阅读,但涉及在不同的实现中一遍又一遍地重新输入 Either[...]。这在后者中得到了解决,但读者乍一看无法对结果做出太多结论。

如果返回类型Option不是Either,我自然会坚持使用以前的版本。对于具有许多类型参数的更复杂的类型,第二个会更有益。Either是中场某处。

我的直觉是,从长远来看,后者更易于维护。你怎么看?有没有这方面的做法?

4

1 回答 1

10

做一个

  1. 将其明确声明为Either[X, Y].
  2. 将其声明为MaybeResult[Y](for type MaybeResult[A] = Either[Failure, A])

坦率地说,即便如此,我也会明确声明。#2(超过您的建议)的优点是,对于标准Failure类型(可能是Exceptionor List[String]),您不必要使用它的任何地方声明单独的类型别名。

使用的好处Either是API 用户100% 清楚正在发生的事情。但是,我会更进一步并使用 Scalaz 的Validation

def someApiCall : ValidationNEL[String, Result]

这里的优点是可以Validation以 Either 不是的方式组合(否则它们是同构类型)。例如:

def a(i : Int) : ValidationNEL[String, Float]
def b(f : Float) : ValidationNEL[String, Boolean]

然后你可以编写:

a(1) >>= b //ValidationNEL[String, Boolean]

像这样:

scala>  def a(i : Int) : ValidationNEL[String, Float] = error("")
a: (i: Int)scalaz.Scalaz.ValidationNEL[String,Float]

scala> def b(f : Float) : ValidationNEL[String, Boolean] = error("")
b: (f: Float)scalaz.Scalaz.ValidationNEL[String,Boolean]

scala> lazy val c = a(1) >>= b
c: scalaz.Validation[scalaz.NonEmptyList[String],Boolean] = <lazy>
于 2011-04-01T12:24:21.527 回答