7

Scalaで任意の関数の逆を表現する方法はありますか?

たとえば、次のfような関数があるとします。

(x: Int) => x + 1

次のような逆関数を記述できるようにしたいと思いますg

(f(x): Int) => x // not a valid scala syntax

また

(x: Int) => inverse(f(x)) // inverse would return (x => x -1)

Scalaでこの種のことを行う方法を知っていますか?

注意:x => x+1これは単なる例です。この種のタスクを解決する一般的な方法を探しています。

4

5 に答える 5

16

いいえ、そのようなことはできません。問題は、すべての数学関数に逆数があるわけではないことです。逆関数に関するウィキペディアのエントリから:

すべての関数に逆関数があるわけではありません。このルールを適用するには、各要素 y ∈ Y が 1 つ以下の x ∈ X に対応している必要があります。この性質を持つ関数 ƒ は、1 対 1、情報保存、または注入と呼ばれます。

たとえば、平方根 ( ) 関数は、平方根関数が 1 対 1 の場合にのみsqrt平方関数 ( ) の逆になります。の理由だけで、平方根関数の負は平方関数の逆であると言えます。しかし、これは二乗関数の特殊な性質であり、一般的には正しくありません。x^2x >= 0x < 0x^2 = (-x)^2

于 2012-09-27T06:25:42.387 に答える
2

関数の逆関数を表現することはできませんが、その結果の逆関数を表現することはできます。おそらくそれが適しています。

これは、関数を渡すときに便利です。

たとえば、f: Int => Boolean高階関数のパラメーターとして使用している関数がある場合x => !f(x)、計算結果の逆関数を返すだけの同じタイプの別の関数でラップできます。

def select(ls: List[String], p: String => Boolean): List[String] =
  ls.remove(x => !p(x))
// select: (ls: List[String], p: String => Boolean)List[String]

val li = List("one", "two", "three")
// li: List[java.lang.String] = List(one, two, three)

/* using select with some conditions */
select(li, _.length() > 3)  // equivalent to select(li, x => x.length() > 3)
// res0: List[String] = List(three)
select(li, _.length() <= 3) // equivalent to select(li, x => x.length() <= 3)
// res1: List[String] = List(one, two)

/* using remove with the same conditions */
li.remove(_.length() > 3)  // equivalent to li.remove(x => x.length() > 3)
// res2: List[java.lang.String] = List(one, two)
li.remove(_.length() <= 3)  // equivalent to li.remove(x => x.length() <= 3)
// res3: List[java.lang.String] = List(three)

注:removeクラスのメソッドListは非推奨であり、代わりに使用する必要がありますが、この例では読みやすくなっfilterNotていると思います。remove

于 2012-10-02T18:33:19.233 に答える
2

実用的な観点から、unapplyメソッドを使用して逆関数を表すことができます。

object f {
  def apply(x: Int) = x + 1
  def unapply(x: Int) = Some(x - 1);
}

val x = 1
val f(y) = f(x)

assert(x == y)
于 2014-01-08T13:38:12.690 に答える
0

この質問の重複としてマークされた別の質問のために回答を追加していますが、まだ誰もこれについて言及していないようです:理論的には、「逆数」を自動的に計算することは可能です (入力に対して徹底的な検索を実行するという意味で、 2 進数の無限シーケンスに対する関数の解が有限の時間内に存在しない場合は「なし」と答えます。記事「一見不可能な関数型プログラム」を参照してください(ただし、Scala ではなく Haskell を使用しています)。

もちろん、この網羅的な検索の実用性は別の問題です。

于 2016-07-04T02:50:23.380 に答える