2016-08-30 15 views
6

Tôi đang chơi với Scala (z) để học lập trình hàm.Tương lai [Liệt kê [Lỗi /Đôi]] thành Tương lai [[Danh sách [Lỗi] /Danh sách [Đôi]] trong Scala

Tôi có giá trị loại Future[List[Error \/ Double]] và muốn chuyển đổi thành loại nào đó với loại Future[[List[Error] \/ List[Double]].

Mục tiêu là nhóm các giá trị và quyền.

Tôi hiện có như sau:

val foo: Future[List[Error] \/ List[Double]] = { 
    for { 
    results <- resultsF 
    } yield 
    results.foldLeft(\/[List[Error], List[Double]])({ 
     case (acc, v) if v.isRight => v :: \/-(acc) 
     case (acc, v) if v.isLeft => v :: -\/(acc) 
    }) 
} 

Tuy nhiên, tôi nhận được một lỗi trên :: đó là do thực tế rằng ắc tôi không phải là một danh sách (từ bên ngoài) \/[List[Error], List[Double]]. Làm thế nào nó nên được thực hiện?

Trả lời

5

Chức năng này trong Haskell sẽ là partitionEithers: [Either a b] -> ([a], [b]).

(Bạn không thực sự muốn Either [a] [b], điều đó sẽ không thực sự có ý nghĩa. Tôi đoán bạn muốn chức năng này thay vì của văn bản trong mô tả của bạn ...)

Scalaz không có nó như là. Tuy nhiên, nó có một tổng quát hơn separate:

/** Generalized version of Haskell's `partitionEithers` */ 
def separate[G[_, _], A, B](value: F[G[A, B]])(implicit G: Bifoldable[G]): (F[A], F[B]) 

cơ bản nào là Bifoldable g, MonadPlus f => f (g a b) -> (f a), (f b). Cụ thể: [Either a b] -> ([a], [b]). Bạn có thể chỉ cần gọi nó trên danh sách của bạn (trong đó g = \/ (hoặc Hoặc), f = List).

Trong hành động:

scala> import scalaz._, Scalaz._ 
scala> List(\/-(3), -\/("a")).separate 
res1: (List[String], List[Int]) = (List(a),List(3)) 
+2

Sau khi bạn đã nhập 'scalaz.Scalaz._'. –

+0

@EndeNeu phải, hehe ... Đó là trong tập tin sbtrc của tôi ... Cảm ơn! – Ven

0

đúng ra, bạn có thể thực hiện chức năng như vậy, ví dụ, làm thế nào để bạn áp dụng danh sách này:

-\/(A) :: \/-(B) :: Nil 

Giả danh sách đầu vào còn lại toàn bộ hoặc tất cả các quyền, bạn có thể nhìn trộm cái đầu tiên và quyết định cách xử lý phần còn lại:

val foo: Future[List[Error] \/ List[Double]] = 
    resultsF.map(resultsF.head match { 
    case -\/(_) => { _.left } 
    case \/-(_) => { _.right } 
    }) 

Giả sử bạn muốn nhóm lef ts và quyền, một lần quay trở lại (Danh sách [L], Danh sách [R]) hoạt động hoàn hảo:

val foo[L,R]: Future[(List[L], List[R])] = 
    resultsF.foldr((Nil, Nil)){ (s, v) => 
    case -\/(l) => (l :: s._1, s._2) 
    case \/-(r) => (s._1, r :: s._2) 
    } 
+0

Có, loại câu hỏi không chính xác. Cf "Mục đích là để nhóm các lefts và các quyền." đưa ra gợi ý về những gì mà op tìm kiếm. – Ven

Các vấn đề liên quan