2015-08-24 60 views
0

下面是代碼斯卡拉下界類型」與「另一種類型?

class Result[A] { 
    def map[B](f: (Result[A] => Result[B]), xResult: Result[A]) = { 
     xResult match { 
     case Success(x) => Success(f(xResult)) 
     case Failure(errs) => Failure(errs) 
     } 
    } 

    def apply[B](fResult: Result[A], xResult: Result[B]) = { 
     (fResult, xResult) match { 
     case (Success(f), Success(x))  => Success((f, x)) 
     case (Failure(errs), Success(a))  => Failure(errs) 
     case (Success(a), Failure(errs))  => Failure(errs) 
     case (Failure(errs), Failure(errs2)) => Failure(List(errs, errs2)) 
     } 
    } 
    } 

    case class Success[A](a: A) extends Result[A] {} 

    case class Failure[A](a: A) extends Result[A] {} 

    def createCustomerId(id: Int) = { 
    if (id > 0) 
     Success(id) 
    else 
     Failure("CustomerId must be positive") 
    } 

這裏有問題

1)從類型推斷是由於方法createCustomer是這樣

Product with Serializable with Result[_ >: Int with String] 

我沒有用「的產品與序列化的麻煩「東西,我想知道的是如何做到對結果有意義的事情,並且出於好奇如何初始化類型。

假設我有另一種方法如下圖所示

def createCustomer(customerId: Result[_ >: Int with String], email: Result[String]) = { 
    how can i read/do something with "customerId" argument 
    } 

如何初始化類像

val x: Result[Int with String] = ??? 

筆記:

  1. 我知道我的結果類可是沒有任何通用「getter」
  2. 我知道也許事情可能是ea sier在方法「createCustomerId」,如果當id> 0時,我返回成功(id.ToString),但我真的想知道這種較低類型正在發生什麼以及未來我如何利用(如果可能)

回答

1

問題是您的類型定義指出SuccessFailure都採用相同的參數類型。但是,您實際上想要在保持協方差的同時將其他類型的參數放入Failure。這是最簡單的解決辦法:

class Result[A] { 

    def map[B](f: (Result[A] => Result[B]), xResult: Result[A]) = { 
    xResult match { 
     case Success(x) => Success(f(xResult)) 
     case Failure(errs) => Failure(errs) 
    } 
    } 

    def apply[B](fResult: Result[A], xResult: Result[B]) = { 
    (fResult, xResult) match { 
     case (Success(f), Success(x)) => Success((f, x)) 
     case (Failure(errs), Success(a)) => Failure(errs) 
     case (Success(a), Failure(errs)) => Failure(errs) 
     case (Failure(errs), Failure(errs2)) => Failure(List(errs, errs2)) 
    } 
    } 
} 

case class Success[A](a: A) extends Result[A] {} 

case class Failure[A, B](a: B) extends Result[A] {} 

object TestResult extends App { 

    def createCustomerId(id: Int): Result[Int] = { 
    if (id > 0) 
     Success(id) 
    else 
     Failure("CustomerId must be positive") 
    } 

    println(createCustomerId(0)) 
    println(createCustomerId(1)) 
} 

打印:

Failure(CustomerId must be positive) 
Success(1) 

如果沒有標註返回類型爲createCustomerIdResult[Int]編譯器會推斷Result[_ <: Int] with Product with Serializable這可能不理想,但不是太糟糕。