简体   繁体   English

Scala - 为紧凑性定义Either的类型,还是为了可读性而明确写入?

[英]Scala - Define type for Either for compactness or write it explicitly for readability?

In Scala, I can have: 在Scala中,我可以:

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

or 要么

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

trait Api {
    def someApiCall: SomeObject.SomeResult;
}

where the former is more explicit about the result type and thus easier to read, but involves retyping Either[...] over and over in different implementations. 前者对结果类型更明确,因此更容易阅读,但涉及在不同的实现中反复重新输入。 This is solved in in the latter, but then the reader can't conclude much about the result at first sight. 这在后者中得到了解决,但是后来读者无法对第一眼的结果作出很多结论。

If the return type were Option instead of Either , I would naturally stick with the former version. 如果返回类型是Option而不是Either ,我自然会坚持使用前一版本。 For more complex types with many type parameters, the second would be more beneficial. 对于具有许多类型参数的更复杂类型,第二类更有益。 Either is somewhere midfield. Either是中场的某个地方。

My gut feeling is that on the long run the latter is more maintainable. 我的直觉是,从长远来看,后者更易于维护。 What do you think? 你怎么看? Is there a practice regarding this? 对此有实践吗?

Do one of 做其中一个

  1. Declare it explicitly as an Either[X, Y] . 将其明确声明为Either[X, Y]
  2. Declare it as MaybeResult[Y] (for type MaybeResult[A] = Either[Failure, A] ) 将其声明为MaybeResult[Y] (对于type MaybeResult[A] = Either[Failure, A]

Frankly, even then I would declare it explicitly. 坦率地说,即便如此,我也会明确地宣布它。 The advantage of #2 (over your suggestion) is that, with a standard Failure type (perhaps Exception or List[String] ), you do not have to declare separate type aliases for everywhere you want to use this. #2(你的建议)的优点是,与一个标准的Failure类型(可能是ExceptionList[String] ),你不必申报分离型别名无处不在,你想用这个。

The advantage to using Either is that it is 100% clear for an API user what is happening. 使用Either的优势在于,对于API用户来说,它是100%清晰的。 However, I would go one step further and use Scalaz's Validation : 但是,我会更进一步使用Scalaz的Validation

def someApiCall : ValidationNEL[String, Result]

The advantage here is that Validation is composable in ways that Either is not (otherwise they are isomorphic types). 这里的优点是Validation可以以不同的方式组合(否则它们是同构类型)。 For example: 例如:

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

Then you can compose: 然后你可以撰写:

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

Like so: 像这样:

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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM