9

暗黙のリフティングを定義したい。関数 A => B があるとします。これを Maybe に持ち上げる方法を定義したいと思います。つまり、Maybe[A] => Maybe[B] です。

これは、暗黙的な変換で簡単に実行できます。ただし、2 つ以上のパラメーターを持つ関数で同じことをしたい場合は、問題があります。私が知っている唯一の解決策は、コードを複製することです。

任意の数のパラメーターを持つ任意の関数に対して、このようなリフティングを重複なく実装したいと考えています。これはScalaで可能ですか?

4

1 に答える 1

18

functor インスタンスが利用可能な場合、任意の関数をFに持ち上げることができます。A => BF[A] => F[B]

Applicative functor インスタンスが利用可能な場合、任意の関数をFに持ち上げることができます。基本的に、アプリケーション ファンクターは、任意のアリティのファンクターを一般化したものです。A => B => C => .. => ZF[A] => F[B] => F[C] => .. => F[Z]

functor と applicative functor については、ここここで学ぶことができます。これらのアイデアをカバーするこの優れた講演もあります。

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

カリー化された関数は構文的に重いため、あまり使用されないため、 Scalazliftは on などのメソッドをpimpします。舞台裏では、リフティングはs (つまり、カリー化された関数) で行われます。Function2Function3Function1

Scalaz のソース コードも参照してください。

于 2012-07-08T22:11:46.577 に答える