Se F
ha un'istanza di functor disponibile, è possibile sollevare qualsiasi funzione da A => B
a F[A] => F[B]
.
Se F
dispone di un'istanza di functor applicativo disponibile, è possibile sollevare qualsiasi funzione da A => B => C => .. => Z
a F[A] => F[B] => F[C] => .. => F[Z]
. Essenzialmente, il functor applicativo è una generalizzazione del funtore per l'arbitar arbitrario.
È possibile conoscere i funtori funzionali e applicativi here e here. C'è anche il this discorso eccellente che copre queste idee.
La libreria Scalaz fornisce queste astrazioni (e altro ancora!).
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 protettori lift
metodo su Function2
, Function3
ecc perché funzioni al curry essendo syntactially più pesanti sono usati meno spesso. Dietro le quinte, il sollevamento avviene con Function1
s (cioè funzioni al curry).
Si potrebbe anche voler dare un'occhiata a Scalaz source code.
Questo potrebbe valere la pena guardare: http://blog.tmorris.net/lifting/ –
Dai un'occhiata a http://www.scala-lang.org/api/current/index.html#scala.Function2 , nota la funzione tupla. Anche http://www.scala-lang.org/api/current/index.html#scala.Function$ metodi tupled e unupupled. – pedrofurla