web-dev-qa-db-ja.com

ファーストクラスの市民機能とは何ですか?

ファーストクラスの市民機能とは何ですか?

Javaはファーストクラスの市民機能をサポートしていますか?

編集:
Wikepedia で言及したとおり

関数型プログラミングスタイルには、ファーストクラスの関数が必要です。

ファーストクラスの機能の他の使用はありますか?

44
Alpine

プロシージャを「ファーストクラス」と見なす言語を使用すると、他の値と同じように関数を渡すことができます

Java 7(およびそれ以前)およびCのような言語にはこの機能があります。Cは関数ポインタを渡すことができますが、これらの言語で関数を動的に定義することはできず、突然Javaバージョン8より前は、これを匿名クラスである程度シミュレートできますが、そうします技術的には一流の機能はありません。

一方、C++、D、C#、Visual Basic .NET、Java 8+、および関数型言語(SchemeやHaskellなど))do変数などの関数を渡すことができます。たとえば、次のコードは、入力にaddendを追加する関数を返します

Dで書かれた:

_int delegate(int) makeAdder(int addend) //Returns a function
{
    return delegate int(int x) //Long way
    {
        return x + addend; //Notice that addend came from _outside_ the function
    };

    return (int x) { return x + addend; }; //Short way

    return x => addend + x; //Super-short way, introduced in D 2.058
}
_

C#で記述:

_Func<int, int> MakeAdder(int addend) //Returns a function
{
    return delegate(int x) //The long way. Note: Return type is implicitly 'int'
    {
        return x + addend;
    };

    return x => x + addend; //Short way: x "goes to" (x + addend); inferred types
}
_

C++で記述:

_#include <functional>

std::function<int(int)> make_adder(int addend)
{
    return [=](int x)
    {
        return addend + x;
    };
}
_

Scalaで書かれています:

_def makeAdder(addend: Int) = (x: Int) => addend + x
_

Pythonで書かれています。

_def make_adder(addend):
    def f(x):
        return addend + x
    return f
    # or...
    return lambda x: addend + x
_

アーランで書かれました:

_make_adder(Addend) ->
    fun(X) -> Addend + X end.
_

JavaScriptで記述:

_function makeAdder(addend) {
    return function(x) {
        return addend + x;
    };
}
_

JavaScriptで記述(ES2015アロー関数構文):

_const makeAdder = addend => x => addend + x;
_

スキームで書かれました:

_(define (makeAdder addend)
  (lambda (x)
    (+ x addend)))
_

Haskellで書かれています。

_makeAdder :: Int -> (Int -> Int)
makeAdder addend = \x -> addend + x
_

Visual Basic 2008で記述:

_Function MakeAdder(addend As Integer) As Func(Of Integer, Integer)
    Return Function(x) (x + addend)
End Function
_

Swift(詳細な実装と簡略化した実装の両方)で記述):

_func makeAdder(append: Int) -> (x: Int) -> Int {
    return { (x: Int) -> Int in
        return x + append
    };
}

func makeAdder(append: Int) -> (Int) -> Int {
    return {$0 + append};
}
_

(ちなみに、「ラムダ」は名前のない関数です。ラムダは、ファーストクラスの関数をサポートする言語でのみサポートされています。)

51
user541686

ファーストクラスの関数を渡すことができます。典型的な例はマップ関数です。リストの要素を二乗するScalaの例を次に示します。

val square = (x:Int) => x*x

val squaredList = List(1,2,3,4).map(square _)
//--> List(1,4,9,16)

ここでは、square関数は、すべての要素に適用されるmapメソッドへの引数です。 Javaでこのようなことをしたい場合は、次のようなクラスでラップされたメソッドを使用する必要があります。

interface F<A,B>{ B apply(A a); }

static <A,B> List<B> map(List<A> list, F<A,B> f) {
  List<B> result = new ArrayList<B>();
  for(A a:list) result.add(f.apply(a));
  return result;   
}

//we have to "wrap" the squaring operation in a class in order to make it a function
F<Integer,Integer> square = new F<Integer,Integer>(){ 
  Integer apply(Integer a) { return a*a; }
}

List<Integer> ints = Arrays.<Integer>asList(1,2,3,4);
List<Integer> squares = map(ints, square);

これを見ると、Javaで同じタスクを実行できますが、オーバーヘッドが多く、言語による「ネイティブ」サポートはありませんが、回避策(ラッパークラス)を使用することがわかります。したがって、Javaはファーストクラスの関数をサポートしていませんが、それらを「シミュレート」できます。

うまくいけば、Java 8はファーストクラスの機能をサポートします。これをサポートしたい場合nowは、 http://functionaljava.org/ または http://functionalj.sourceforge.net/ 、またはScala言語をご覧ください。

3
Landei

関数がファーストクラスの市民である関数型プログラミングパラダイムの例を考えてみましょう。関数がファーストクラスの市民であると言うと、関数を使用して次のことができます...

  • 関数を変数に割り当てることができます
  • 関数はデータ構造に格納できます
  • 関数を引数として他の関数に渡すことができます
  • 関数は関数から返すことができます

関数型プログラミング言語では、上記のことを行うことができます。

ここで、Javaがファーストクラスのシチズン関数をサポートしているかどうかを確認します。

Javaでは、メソッドは関数と同等です。メソッドで上記のいずれかを行うことはできません。しかし、上記のすべてはJavaオブジェクトで可能です。つまり、objectsはJavaの最初のクラスの市民です。確かに、Java8は、関数インターフェースとラムダ式を使用して、メソッド(正確にはメソッドの動作)を他のメソッドに渡すことをサポートしています。しかし、それはJavaがファーストクラスの市民としての機能を持っているという意味ではありません。

関数の受け渡し、関数からの関数の戻りなど、上記のことを実行する機能は非常に強力で便利です。これは、データだけでなく動作を渡すことができるためです。

1

ウィキペディアの定義 は非常に優れています。これは、他のデータと同じように渡すことができる関数です。 Javaはそれらをサポートしますサポートしませんそれらが最も近いものはRunnableおよびCallableオブジェクトです。

1
Ted Hopp

いいえ、たとえば、メソッドを変数に割り当てたり、別のメソッドに引数として渡すことはできません。

代わりに、インターフェースを使用して目的の動作をラップしたり、リフレクションを使用してメソッドを具体化したりできます。

0
eljenso

関数は一流の市民であり、変数のようにどこにでも関数を渡すことができます。

Scalaから

def isOdd(in: Int) = in % 2 == 1
val n = (1 to 10).toList
n.filter(isOdd)

see here: isOdd is a function. passed as if it's a variale.

ObjectsはJavaの第一級市民です。 ファーストクラスの市民はどこにでも渡せるものです。パラレルは国のファーストクラスの市民から許可されますほぼどこでも

読んだ:

0
Nishant