我想用隐式定义提升。假设我们有一个函数A => B,我想定义如何将其提升到Maybe,即Maybe [A] => Maybe [B]。
这可以通过隐式转换简单地完成。但是,如果要对具有两个或多个参数的函数执行相同的操作,则会遇到问题。我知道的唯一解决方案是重复代码。
我想对具有任意数量参数的任意函数实现这种提升,而无需重复。在Scala中这可能吗?
最佳答案
如果F
具有可用的仿函数实例,则可以将任何函数A => B
提升为F[A] => F[B]
。
如果F
具有可用的应用仿函数实例,则可以将任何函数A => B => C => .. => Z
提升为F[A] => F[B] => F[C] => .. => F[Z]
。本质上,可应用仿函数是任意Arity的仿函数的泛化。
您可以了解仿函数和应用仿函数here和here。还有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
Scalaz在
lift
和Function2
等上使用Function3
方法,因为语法上较重的 curry 函数使用较少。在后台,通过Function1
(即 curry 函数)进行提升。您可能还想看看Scalaz source code。
关于scala - Scala中的提升功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11386963/