What does "ap" of \/ in Scalaz do?
I am looking at disjunction type of scalaz and I noticed method 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(_)))
I guess I understand what it does. Now I wonder when and why one should actually use it ? Are there any examples of using this ap
function ?
The disjunction you are looking for:
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)
}
Update
To understand how EitherT
and ap
works, think of an Option
, which has Some
and None
and potential matches. With an Option
, you would do:
for {
a <- someOption
} yield ..
With scalaz./
, you usually put an Exception
on the left and a "correct" return type on the right. ap
is a function that says apply this if the either has the correct type.
for {
correctResponse <- ap(someEitherReturnMethod)
}
Use cases
The most common things I can think off where I use them avidly is complex asynchronous flows, such as OAuth1 or OAuth2, where I care about fine grained chaining of errors.
You can use /
as the return of a Future
:
def someComplexThirdPartyApiCall: Future[/[Exception, CorrectReturn]] = {
}
Because you can flatMap
over futures, you can chain a couple methods like the above, collect and propagate errors.
Example
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
}
链接地址: http://www.djcxy.com/p/78266.html
上一篇: openCV AdaptiveThreshold与Otsu阈值。 投资回报率
下一篇: \ Scalaz中的“ap”是做什么的?