これら2つのプログラミング概念の違いを理解したいと思います。前者はデータ型がないことを表し、後者では型は存在しますが情報はありません。さらに、ユニットは関数型プログラミングの理論的基盤に由来することを認識していますが、ユニットプリミティブのユーザビリティが何であるかをまだ理解できません(たとえば、F#プログラムで)。
2 に答える
ユニットタイプは、すべてをより規則的にします。ある程度まで、F#のすべての関数は、単一のパラメーターを取り、単一の結果を返すものと考えることができます。パラメータを必要としない関数は、実際にはパラメータとして「単位」を取り、結果を返さない関数は、結果として「単位」を返します。これにはさまざまな利点があります。1つは、C#で、値を返すさまざまなアリティの関数を表す多数の「Func」デリゲートと、値を返さない多数の「Action」デリゲートの両方が必要であると考えてください(たとえばFunc<int,void>
、合法ではないため、voidそれは完全に「実際の」タイプではないため、そのように使用することはできません)。
F#関数の型も参照してください:タプルとカリー化を楽しむ
関数型プログラミングでは、通常、入力を出力にマッピングすることについて話します。これは文字通り、引数をその戻り値にマッピングすることを意味します。しかし、何かが数学/圏論の意味で関数になる場合、それは何かを返さなければなりません。値は、関数が何も返さないことを表します。void
これは、これらの用語では無意味です。
unit
に対する機能的な答えvoid
です。これは基本的に、値が1つしかないタイプ()
です。さまざまな用途がありますが、ここでは簡単なものを紹介します。より伝統的な命令型言語でこのようなものがあったとしましょう:
public static <T, U> List<U> map(List<T> in, Function<T, U> func) {
List<U> out = new ArrayList<U>(in.size());
for (T t : in) {
out.add(func.apply(t));
}
return out;
}
これにより、リスト上のすべての要素に特定の関数が適用され、の出力タイプのfunc
新しいリストが生成されます。しかし、引数を出力するだけの関数を渡すとどうなりますか?出力タイプがないので、何を入れることができますか?func
U
void
一部の言語では、このような関数を渡すと、このコードが壊れます(C#のように、ジェネリック型に割り当てることができません)。Action<T>
が不格好になる可能性があるなどの回避策に頼る必要があります。
ここで、の概念unit
が役立ちます。これは型ですが、単一の値しかとらない場合があります。これにより、チェーンや構成などが大幅に簡素化され、心配する必要のある特殊なケースの数が大幅に削減されます。