2011-04-01 4 views
4

、私が持つことができます。Scala - 型を定義してコンパクト化するか、または読みやすくするために明示的に記述しますか? Scalaで

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

または

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

trait Api { 
    def someApiCall: SomeObject.SomeResult; 
} 

を前者はより多くの結果の型についての明示的なので、読みやすいですが、どちらかを再入力含む場合[...]上さまざまな実装で上書きされます。これは後者では解決されますが、読者は一見して結果について多くのことを結論づけることはできません。

戻り値の型がEitherの代わりにOptionの場合、当然前のバージョンに固執します。多くの型パラメータを持つより複雑な型の場合、2番目の方がより有益です。 Eitherはどこかの中盤です。

私の直感は、長期的には後者がより保守的であるということです。どう思いますか?これに関して練習はありますか?

答えて

10

  1. のいずれかの操作を行いますがEither[X, Y]として明示的に宣言します。
  2. 率直に言って(type MaybeResult[A] = Either[Failure, A]用)MaybeResult[Y]として

それを宣言し、その後も私は明示的に宣言します。 #2の利点は、標準Failureタイプ(おそらくExceptionまたはList[String])の場合、ではないことです。は、これを使用するすべての場所で別々のエイリアスを宣言する必要があります。

Eitherを使用する利点は、APIユーザーのために100%clearです。しかし、私はさらに一歩行くだろうとScalazのValidationを使用します。

def someApiCall : ValidationNEL[String, Result] 

ここでの利点はValidationは、どちらかが(そうでない場合は、同型型である)ではない方法で構成可能であるということです。たとえば:

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> 
+0

感謝を!また、検証を指すため – ron