2011-04-01 2 views
4

В Scala, я могу иметь:Scala - Определить тип для Либо для компактности или записать его явно для удобочитаемости?

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

или

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

trait Api { 
    def someApiCall: SomeObject.SomeResult; 
} 

где бывший более четко о типе результата, и, таким образом, легче читать, но включает в себя перепечатывать либо [...] над и в разных реализациях. Это решается в последнем, но тогда читатель не может заключить много о результатах с первого взгляда.

Если тип возврата был Option вместо Either, я бы, естественно, придерживался прежней версии. Для более сложных типов со многими параметрами типа вторая будет более выгодной. Either - это где-то полузащитник.

У меня возникает ощущение, что в конечном итоге последнее более удобно. Как вы думаете? Есть ли практика в этом отношении?

ответ

10

ли один из

  1. Объявите это явно как Either[X, Y].
  2. Объявить как MaybeResult[Y] (для type MaybeResult[A] = Either[Failure, A])

Честно говоря, даже тогда я бы объявить его в явном виде. Преимущество № 2 (над вашим предложением) состоит в том, что со стандартом Failure (возможно, Exception или List[String]) вы должны не должны объявить отдельные псевдонимы типов везде, где вы хотите использовать это.

Преимущество использования Either заключается в том, что оно 100% ясно для пользователя API, что происходит. Тем не менее, я хотел бы сделать еще один шаг и использовать 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