问题描述
我正在查看 析取 类型的scalaz,我注意到方法ap
我想我明白它的作用了.现在我想知道何时以及为什么应该实际使用它?有没有使用这个 ap
函数的例子?
您正在寻找的分离:
import scalaz.{ \/, -\/\/-, EachT }导入 scalaz.syntax.ToIdOps对象测试扩展 ToIdOps//左右方法来自那里 {//假设你有以下方法def someMethod(flag: Boolean): \/[Exception, SomeObject] {if (flag) someObj.right else new Exception("this is a sample").left}}//模式匹配val x = someMethod 匹配 {case \/-(right) =>//这是 someObjectcase -\/(err) =>//处理错误}//变形def methodThatDealsWithObj(obj: someObject)def methodThatDealsWithErr(err: Exception)someMethod.fold(methodThatDealsWithObj)(methodThatDealsWithErr)//用于理解//ap 的行为就像EitherT.为了 {正确响应<-EitherT(someMethod)}
更新
要了解 EitherT
和 ap
的工作原理,请考虑一个 Option
,其中包含 Some
和 无
和潜在的匹配.使用 Option
,您可以:
for {一个 <- someOption} 屈服 ..
使用scalaz.\/
,你通常在左边放置一个Exception
,在右边放置一个正确"的返回类型.ap
是一个函数,表示如果两者都具有正确的类型,则应用它.
for {正确响应 <- ap(someEitherReturnMethod)}
用例
我最喜欢使用它们的地方是复杂的异步流,例如 OAuth1 或 OAuth2,我关心的是细粒度的错误链接.
您可以使用 \/
作为 Future
的返回:
def someComplexThirdPartyApiCall: Future[\/[Exception, CorrectReturn]] = {}
因为你可以flatMap
覆盖futures,你可以像上面那样链接几个方法,收集和传播错误.
示例
def method1: Future[\/[Exception, String]]def method2(result: String): Future[\/[Exception, String]]def chainExample:Future[\/[Exception, Int]] = {为了 {firstResult <-EitherT(method1)secondResult <-EitherT(method2(firstResult))产生 secondResult.toInt}
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
}
这篇关于“ap"是什么意思?\/在Scalaz 中做什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!