我有一個ADT這是本質Option
和Try
之間的交叉如何創建通過值內Iteratee傳遞一個Iteratee:除非特定值時發現
sealed trait Result[+T]
case object Empty extends Result[Nothing]
case class Error(cause: Throwable) extends Result[Nothing]
case class Success[T](value: T) extends Result[T]
(假設像map
共同組合子,flatMap
等在結果上定義)
給定一個Iteratee[A, Result[B]
稱爲inner
,我想創建一個新的Iteratee[Result[A], Result[B]]
有以下行爲:
- 如果輸入的是
Success(a)
,飼料a
到inner
- 如果輸入的是一個
Empty
,無操作 - 如果輸入的是一個
Error(err)
,我想inner
被完全忽略,而不是返回Done
作爲其結果迭代Error(err)
。
實例行爲:
// inner: Iteratee[Int, Result[List[Int]]]
// inputs:
1
2
3
// output:
Success(List(1,2,3))
// wrapForResultInput(inner): Iteratee[Result[Int], Result[List[Int]]]
// inputs:
Success(1)
Success(2)
Error(Exception("uh oh"))
Success(3)
// output:
Error(Exception("uh oh"))
這聲音,我喜歡這份工作爲Enumeratee
,但我一直沒能在the docs看起來像它會做我想做什麼,發現了什麼,內部的實現對我來說依然是巫術。
如何實現wrapForResultInput
來創建上述行爲?
添加一些不會真正適合評論更多詳細信息:
是的,它看起來像我是在我的問題是錯誤的。我用Iteratees
來描述它,但似乎我真的在尋找Enumeratees
。
在我正在建造的API中的某個點上,有一個Transformer[A]
類,實質上是Enumeratee[Event, Result[A]]
。我希望允許客戶通過提供Enumeratee[Result[A], Result[B]]
來轉換該對象,這將導致Transformer[B]
又名Enumeratee[Event, Result[B]]
。
對於更復雜的例子,假設我有一個Transformer[AorB]
,並希望把它轉換成一個Transformer[(A, List[B])]
:
// the Transformer[AorB] would give
a, b, a, b, b, b, a, a, b
// but the client wants to have
a -> List(b),
a -> List(b, b, b),
a -> Nil
a -> List(b)
客戶端可以實現一個Enumeratee[AorB, Result[(A, List[B])]]
不使用Enumeratee.grouped
太麻煩,但他們需要提供一個Enumeratee[Result[AorB], Result[(A, List[B])]
這似乎介紹了很多併發症,我想盡可能隱藏起來。
val easyClientEnumeratee = Enumeratee.grouped[AorB]{
for {
_ <- Enumeratee.dropWhile(_ != a) ><> Iteratee.ignore
headResult <- Iteratee.head.map{ Result.fromOption }
bs <- Enumeratee.takeWhile(_ == b) ><> Iteratee.getChunks
} yield headResult.map{_ -> bs}
val harderEnumeratee = ??? ><> easyClientEnumeratee
val oldTransformer: Transformer[AorB] = ... // assume it already exists
val newTransformer: Transformer[(A, List[B])] = oldTransformer.andThen(harderEnumeratee)
所以,我正在尋找的是???
,以緩解對誰已經實施easyClientEnumeratee
用戶的負擔定義harderEnumeratee
。
我猜???
應該是一個Enumeratee[Result[AorB], AorB]
,但如果我嘗試像
Enumeratee.collect[Result[AorB]] {
case Success(ab) => ab
case Error(err) => throw err
}
錯誤實際上將拋出;我實際上想讓錯誤以Error(err)
的形式返回。
哦,我剛剛意識到。只要發生錯誤,就要完成Iteratee .... – Odomontois
這是正確的。 – Dylan