我正在研究scalaz的析取类型,我注意到了方法ap
/** Apply a function in the environment of the right of this disjunction. */ def ap[AA >: A, C](f: => AA \/ (B => C)): (AA \/ C) = f flatMap (ff => map(ff(_)))
我想我明白它的作用.现在我想知道何时以及为什么要实际使用它?有没有使用此ap
功能的例子?
您正在寻找的析取:
import scalaz.{ \/, -\/ \/-, EitherT }
import scalaz.syntax.ToIdOps
object Testing extends ToIdOps // left and right methods come from there {
// say you have the following method
def someMethod(flag: Boolean): \/[Exception, SomeObject] {
if (flag) someObj.right else new Exception("this is a sample").left
}
}
// pattern matching
val x = someMethod match {
case \/-(right) => // this is someObject
case -\/(err) => // deal with the error
}
// catamorphism
def methodThatDealsWithObj(obj: someObject)
def methodThatDealsWithErr(err: Exception)
someMethod.fold(methodThatDealsWithObj)(methodThatDealsWithErr)
// for comprehensions
// ap behaves just like EitherT.
for {
correctResponse <- EitherT(someMethod)
}
Run Code Online (Sandbox Code Playgroud)
更新
要了解EitherT
和 的ap
工作原理,请考虑Option
,它具有Some
和None
以及潜在的匹配项。使用Option
,你会这样做:
for {
a <- someOption
} yield ..
Run Code Online (Sandbox Code Playgroud)
使用 时scalaz.\/
,您通常会Exception
在左侧放置一个“正确”的返回类型,在右侧放置一个“正确”的返回类型。ap
是一个函数,表示如果其中一个具有正确的类型,则应用此函数。
for {
correctResponse <- ap(someEitherReturnMethod)
}
Run Code Online (Sandbox Code Playgroud)
用例
我能想到的最常见的事情是我热衷于使用它们的地方是复杂的异步流程,例如 OAuth1 或 OAuth2,我关心的是细粒度的错误链接。
您可以用作\/
a 的返回Future
:
def someComplexThirdPartyApiCall: Future[\/[Exception, CorrectReturn]] = {
}
Run Code Online (Sandbox Code Playgroud)
因为您可以flatMap
通过 future,所以您可以链接上面的几个方法,收集和传播错误。
例子
def method1: Future[\/[Exception, String]]
def method2(result: String): Future[\/[Exception, String]]
def chainExample: Future[\/[Exception, Int]] = {
for {
firstResult <- EitherT(method1)
secondResult <- EitherT(method2(firstResult))
} yield secondResult.toInt
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
562 次 |
最近记录: |