简体   繁体   English

Scalaz中*>和<*的目的是什么?

[英]What is the purpose of *> and <* in Scalaz

Let's take a look at the implementation of finish on a Scalaz Task 让我们来看看Scalaz Task上的finish的实现

def onFinish(f: Option[Throwable] => Task[Unit]): Task[A] =
    new Task(get flatMap {
        case -\/(e) => f(Some(e)).get *> Future.now(-\/(e))
        case r => f(None).get *> Future.now(r)
    })

What is the *> accomplishing here? 什么是*>在这里完成?

This is the Apply syntax. 这是Apply语法。 I recently added some examples of using the apply syntax to the examples sub-project of scalaz, you can see specifically some discussion of *> and <* here: 我最近添加了一些使用apply语法到scalaz的examples子项目的例子,你可以在这里特别看到*><*讨论:

https://github.com/scalaz/scalaz/blob/series/7.2.x/example/src/main/scala/scalaz/example/ApplyUsage.scala#L94-L130 https://github.com/scalaz/scalaz/blob/series/7.2.x/example/src/main/scala/scalaz/example/ApplyUsage.scala#L94-L130

The idea is that you are evaluating two 'effectful' computations on either side of the combinator, using the Apply instance to combine the effects, but throwing away one of the resulting values. 这个想法是你正在评估组合器两侧的两个“有效”计算,使用Apply实例来组合效果,但丢弃其中一个结果值。 <* throws away the value on the right, and *> throws away the value on the left. <*抛弃右边的值, *>抛弃左边的值。

In your example, we are using Apply[Future] to combine the effects, and the effect is the delayed computation of the future. 在您的示例中,我们使用Apply [Future]来组合效果,效果是未来的延迟计算。 In the first case match we have this one: 在第一个案例匹配中我们有这个:

 f(Some(e)).get *> Future.now(-\/(e))

So f(Some(e)).get returning the Future[Unit] that the Task is wrapping when we apply the f function, this Task is just being run for its side effects. 所以f(Some(e)).get当我们应用f函数时,返回Task包装的Future[Unit] ,这个Task正在运行它的副作用。 The right half of the apply Future.now(-\\/(e)) is the value we want to return, in a Future , but we want this future to deppend on the result of the side effecting Future[Unit] . 应用Future.now(-\\/(e))的右半部分是我们想要在Future返回的值,但是我们希望这个未来能够对副作用Future[Unit]的结果产生影响。 The result is that we get a Future[-\\/] , but it is one that won't be complete until the side effect has completed. 结果是我们获得了一个Future[-\\/] ,但是在副作用完成之前它是不完整的。

I find that a good example of where these combinators are easy to understand are parser combinators. 我发现这些组合器易于理解的一个很好的例子是解析器组合器。 Let's assume we have some parser: 我们假设我们有一些解析器:

trait Parser[A]

Which is something that will consume some input and produce an A in the process. 哪个会消耗一些输入并在过程中产生A。 Say we have a method which will parse a character: 假设我们有一个解析角色的方法:

def chr(c: Char): Parser[Char]

and some method which will parse some arbitrary string: 以及一些解析一些任意字符串的方法:

def foo: Parser[String]

then we can make a parser for our arbitrary string inside parentheses: 然后我们可以在括号内为我们的任意字符串创建一个解析器:

val parentheticalFoo: Parser[String] = chr('(') *> foo <* chr(')')

this creates a parser that although it will consume an open parenthesis, then a foo, then a close parenthesis, it will only return the result of parsing the foo. 这会创建一个解析器,虽然它会使用一个开括号,然后是一个foo,然后是一个闭括号,它只会返回解析foo的结果。 We don't care about actually receiving the output of the chr('(') and chr(')') parers, but we want their effects of consuming input to still be combined into the resulting parser. 我们并不关心实际接收chr('(')chr(')') parers的输出,但我们希望它们消耗输入的效果仍然可以合并到生成的解析器中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM