scala中的提升功能

时间:2012-07-08 21:43:51

标签: scala

我想用implicits来定义提升。假设我们有一个函数A => B,我想定义如何将它提升到Maybe,即Maybe [A] =>也许[B]。

这可以通过隐式转换完成。但是,如果我想对具有两个或更多参数的函数执行相同操作,则会出现问题。我知道的唯一解决方案是复制代码。

我想用任意数量的参数实现任意函数的这种提升而不重复。这在Scala中是否可行?

1 个答案:

答案 0 :(得分:18)

如果F有可用的仿函数实例,则可以将任何函数A => B提升为F[A] => F[B]

如果F有可用的应用仿函数实例,则可以将任何函数A => B => C => .. => Z提升为F[A] => F[B] => F[C] => .. => F[Z]。从本质上讲,applicative functor是对任意arity的仿函数的推广。

您可以了解仿函数和应用仿函数herehere。还有this优秀的演讲,涵盖了这些想法。

Scalaz库提供了这些抽象(以及更多!)。

import scalaz._
import Scalaz._

scala> val foo: Int => String = _.toString
foo: Int => String = <function1>

scala> foo.lift[Option]
res0: Option[Int] => Option[String] = <function1>

scala> res0(Some(3))
res1: Option[String] = Some(3)

scala> res0(None)
res2: Option[String] = None

scala> val add: (Int, Int) => Int = _ + _
add: (Int, Int) => Int = <function2>

scala> add.lift[Option]
res3: (Option[Int], Option[Int]) => Option[Int] = <function2>

scala> res3(Some(2), Some(1))
res4: Option[Int] = Some(3)

scala> res3(Some(2), None)
res5: Option[Int] = None

scala> res3(None, None)
res6: Option[Int] = None

liftFunction2等上的Scalaz pimps Function3方法,因为混合函数较多的咖喱函数使用频率较低。在幕后,提升发生在Function1 s(即curried函数)。

您可能还想查看Scalaz source code