[英]What is the purpose of *> and <* in Scalaz
让我们来看看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)
})
什么是*>在这里完成?
这是Apply
语法。 我最近添加了一些使用apply语法到scalaz的examples子项目的例子,你可以在这里特别看到*>
和<*
讨论:
这个想法是你正在评估组合器两侧的两个“有效”计算,使用Apply实例来组合效果,但丢弃其中一个结果值。 <*
抛弃右边的值, *>
抛弃左边的值。
在您的示例中,我们使用Apply [Future]来组合效果,效果是未来的延迟计算。 在第一个案例匹配中我们有这个:
f(Some(e)).get *> Future.now(-\/(e))
所以f(Some(e)).get
当我们应用f
函数时,返回Task
包装的Future[Unit]
,这个Task正在运行它的副作用。 应用Future.now(-\\/(e))
的右半部分是我们想要在Future
返回的值,但是我们希望这个未来能够对副作用Future[Unit]
的结果产生影响。 结果是我们获得了一个Future[-\\/]
,但是在副作用完成之前它是不完整的。
我发现这些组合器易于理解的一个很好的例子是解析器组合器。 我们假设我们有一些解析器:
trait Parser[A]
哪个会消耗一些输入并在过程中产生A。 假设我们有一个解析角色的方法:
def chr(c: Char): Parser[Char]
以及一些解析一些任意字符串的方法:
def foo: Parser[String]
然后我们可以在括号内为我们的任意字符串创建一个解析器:
val parentheticalFoo: Parser[String] = chr('(') *> foo <* chr(')')
这会创建一个解析器,虽然它会使用一个开括号,然后是一个foo,然后是一个闭括号,它只会返回解析foo的结果。 我们并不关心实际接收chr('(')
和chr(')')
parers的输出,但我们希望它们消耗输入的效果仍然可以合并到生成的解析器中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.