让我通过例子澄清我的问题.这是在
Scala中使用尾递归编写的标准取幂算法:
def power(x: Double,y: Int): Double = { def sqr(z: Double): Double = z * z def loop(xx: Double,yy: Int): Double = if (yy == 0) xx else if (yy % 2 == 0) sqr(loop(xx,yy / 2)) else loop(xx * x,yy - 1) loop(1.0,y) }
这里sqr方法用于产生循环结果的平方.看起来不是一个好主意 – 为这样一个简单的操作定义一个特殊的功能.但是,我们不能只写loop(..)* loop(..),因为它会使计算加倍.
我们也可以用val编写它而没有sqr函数:
def power(x: Double,y: Int): Double = { def loop(xx: Double,yy: Int): Double = if (yy == 0) xx else if (yy % 2 == 0) { val s = loop(xx,yy / 2); s * s } else loop(xx * x,y) }
我不能说它看起来比使用sqr更好,因为它使用状态变量.第一种情况更具功能性第二种方式更适合Scala.
无论如何,我的问题是当你需要后处理函数的结果时如何处理案例?也许Scala有其他方法可以实现这一目标?
解决方法
你可以使用“前进管道”.我从这里得到了这个想法:
Cache an intermediate variable in an one-liner.
所以
val s = loop(xx,yy / 2); s * s
可以改写成
loop(xx,yy / 2) |> (s => s * s)
使用像这样的隐式转换
implicit class PipedObject[A](value: A) { def |>[B](f: A => B): B = f(value) }
正如彼得指出的那样:使用隐式值类
object PipedObjectContainer { implicit class PipedObject[A](val value: A) extends AnyVal { def |>[B](f: A => B): B = f(value) } }
像这样使用
import PipedObjectContainer._ loop(xx,yy / 2) |> (s => s * s)
更好,因为它不需要临时实例(需要Scala> = 2.10).
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。