我正在尝试验证无效方法的参数,但我找不到解决方案......
谁能告诉我该怎么办?
我正在尝试这样的事情:
def buildNormalCategory(user: User, parent: Category, name: String, description: String): Either[Error,Category] = {
val errors: Option[String] = for {
_ <- Option(user).toRight("User is mandatory for a normal category").right
_ <- Option(parent).toRight("Parent category is mandatory for a normal category").right
_ <- Option(name).toRight("Name is mandatory for a normal category").right
errors : Option[String] <- Option(description).toRight("Description is mandatory for a normal category").left.toOption
} yield errors
errors match {
case Some(errorString) => Left( Error(Error.FORBIDDEN,errorString) )
case None => Right( buildTrashCategory(user) )
}
}
Run Code Online (Sandbox Code Playgroud) 假设我想从2个远程服务聚合数据,并尽可能快地提供响应:
def loadUser: Future[User]
def loadData: Future[Data]
case class Payload(user: User, data: Data)
Run Code Online (Sandbox Code Playgroud)
我知道这个顺序执行异步任务:
for {
user <- loadUser
data <- loadData
} yield Payload(user,data)
Run Code Online (Sandbox Code Playgroud)
虽然这个并行执行它们,因为异步任务在顺序链接之前被触发:
val userF = loadUser
val dataF = loadData
for {
user <- userF
data <- dataF
} yield Payload(user,data)
Run Code Online (Sandbox Code Playgroud)
然而,差异对我来说有点过于含蓄,有些人可能最初没有注意到它.
申请人也解决了这个问题
(loadUser |@| loadData) { Payload(_,_) }
Run Code Online (Sandbox Code Playgroud)
有人可以告诉我在应用程序和monad之间使用什么来执行并行异步计算吗?每种方法的优缺点是什么?
假设我需要运行两个并发计算,等待它们,然后组合它们的结果.更具体地说,我需要运行f1: X1 => Y1并f2: X2 => Y2同时然后调用f: (Y1, Y2) => Y最终得到一个值Y.
我可以创建未来的计算 fut1: X1 => Future[Y1],fut2: X2 => Future[Y2]然后组合它们以fut: (X1, X2) => Future[Y]使用monadic组合.
问题是monadic组合意味着顺序等待.在我们的例子中,它意味着我们先等待一个未来,然后我们将等待另一个未来.例如.如果它需要2秒.到第一个未来完成,只需1秒.到第二个未来失败,我们浪费1秒.
因此,它看起来像我们所需要的应用性期货的组成等到要么两者完全或至少一个未来的失败.是否有意义 ?你会如何实施<*>期货?
我一直在工作中使用 Scala,为了更深入地理解函数式编程,我选择了 Graham Hutton's Programming in Haskell(喜欢它:)
在关于 Monads 的章节中,我第一次看到了 Applicative Functors (AFs) 的概念
在我(有限的)专业 Scala 能力中,我从来不必使用 AF,并且总是编写使用 Monad 的代码。我试图提炼对“何时使用 AFs”的理解以及由此产生的问题。这种见解是否正确:
如果您的所有计算都是独立且可并行的(即,一个的结果不能确定另一个的输出),如果输出需要通过管道传输到没有影响的纯函数,AF 会更好地满足您的需求。但是,如果你有一个甚至单一依赖的AF不会帮助,你会被强制使用单子。如果需要将输出通过管道传输到具有效果的函数(例如,返回 Maybe),您将需要 Monads。
例如,如果你有这样的“monadic”代码:
val result = for {
x <- callServiceX(...)
y <- callServiceY(...) //not dependent on X
} yield f(x,y)
Run Code Online (Sandbox Code Playgroud)
最好做一些类似的事情(scala 的伪 AF 语法,|@|就像并行/异步调用之间的分隔符)。
val result = (callServiceX(...) |@| callServiceY(...)).f(_,_)
Run Code Online (Sandbox Code Playgroud)
f == pure and callService* are independentAF 可以更好地为您服务f有效果,即,f(x,y): Option[Response]您将需要 MonadscallServiceX(...), y …我有两个monad实例val a: M[A]和val b: M[B].在以下代码情况下会有任何性能差异吗?
def f: (A, B) => C
val applicativeCombine = (a |@| b)(f)
val monadCombine =
for {
aa <- a
bb <- b
} yield f(aa, bb)
Run Code Online (Sandbox Code Playgroud)
......还是依赖?
假设我有一个函数列表E => Either[Exception, Unit]来调用事件E并累积错误以返回Either[List[Exception], Unit].
type EventHandler = E => Either[Exception, Unit]
import cats.data.NonEmptyList
def fire(
e: Event,
subscribers: List[EventHandler]
): Either[NonEmptyList[Exception], Unit] = ???
Run Code Online (Sandbox Code Playgroud)
我想实现fire与cats
import cats.implicits._
subscribers.foldMap (_ map (_.toValidatedNel))
.map (.toEither)
.apply(e)
Run Code Online (Sandbox Code Playgroud)
是否有意义 ?你会如何改进它?
如何更改fire为subscribers同时调用?
我有一个 Option[String] 并且我想确保字符串是小写的。“进入”选项并进行转换而无需提取字符串然后将其放回选项的惯用方法是什么?
谢谢
scala ×7
applicative ×3
monads ×3
concurrency ×2
scala-cats ×2
scalaz ×2
either ×1
future ×1
haskell ×1
monoids ×1
performance ×1