我想用implicits来定义提升。假设我们有一个函数A => B,我想定义如何将它提升到Maybe,即Maybe [A] => Maybe [B]。scala中的提升函数
这可以通过隐式转换简单完成。但是,如果我想对具有两个或更多参数的函数执行相同的操作,则会出现问题。我知道的唯一解决方案是复制代码。
我想用任意数量的参数来实现这种提升任意函数而没有重复。这可能在斯卡拉?
我想用implicits来定义提升。假设我们有一个函数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]
。从本质上讲,应用仿函数是任意仿函数的泛函。
您可以了解仿函数和应用仿函数here和here。涵盖这些想法的还有this优秀的演讲。
斯卡拉斯图书馆提供这些抽象(和更多!)。
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上皮条客Function2
lift
方法,Function3
等因为是syntactially较重咖喱功能不经常使用。在幕后,提升发生在Function1
(即咖喱功能)上。
您可能还想看看Scalaz source code。
奇怪的是'foo.lift [Option]'不能用Scalaz 7编译,但'add.lift [Option]'确实是 – 2012-09-17 12:47:20
@NikitaVolkov,只是在这里猜测...... 1. Functor [Option] .lift (foo)'和'Applicative [Option] .lift2(add)'可能有效。现在公开的“扩展方法”较少。 2.大多数扩展方法仍然可以在'scalaz.syntax'包中找到。你正在寻找的'lift'可能会躺在那里。 – missingfaktor 2012-09-17 13:34:37
是上面的代码应该在Scalaz 7.1和Scala 2.11.5上工作吗? – 2015-01-21 17:15:21
这可能值得一看:http://blog.tmorris.net/lifting/ – 2012-07-08 21:54:25
请看http://www.scala-lang.org/api/current/index.html#scala.Function2 ,注意tupled函数。另外http://www.scala-lang.org/api/current/index.html#scala.Function$元组和未添加的方法。 – pedrofurla 2012-07-08 22:07:29