开发者

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

开发者 https://www.devze.com 2023-02-21 01:13 出处:网络
In Scala, I can have: trait Api { def someApiCall: Either[Failure, GoodResult]; } or object SomeObject { type SomeResult = Eit开发者_运维知识库her[Failure, GoodResult]

In Scala, I can have:

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

or

object SomeObject {
    type SomeResult = Eit开发者_运维知识库her[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. For more complex types with many type parameters, the second would be more beneficial. Either is somewhere midfield.

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].
  2. Declare it as MaybeResult[Y] (for 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.

The advantage to using Either is that it is 100% clear for an API user what is happening. However, I would go one step further and use Scalaz's 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). 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>
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号