私は D をいじり、ラムダ式をチェーンすることでScala スタイルのカリー化可能な関数を模倣しようとしました。
私はこれを思いついた:
immutable foo=function(immutable int x)=>(immutable int y)=>(x+y);
struct S
{
static immutable foo=function(immutable int x)=>(immutable int y)=>(x+y);
}
class C static immutable foo=function(immutable int x)=>(immutable int y)=>(x+y);
}
void main()
{
writefln("global\t%s",foo(1)(2));
writefln("struct\t%s",S.foo(1)(2));
writefln("class\t%s",C.foo(1)(2));
}
これを実行すると、次のようになります。
global 3
struct 1528543170
Segmentation fault
ご覧のとおり、私の方法はグローバル関数変数に対してはうまく機能しますが、構造体の静的関数変数はジャンクな結果を出し、クラスの静的関数変数は完全に失敗します。x
return 式からを削除するとfunction(immutable int x)=>(immutable int y)=>(y)
、構造体バージョンは正しい result( 2
) を返しますが、クラス バージョンはまだ失敗します。
関数変数の代わりに通常のメソッドを使用する場合:
immutable foo=function(immutable int x)=>(immutable int y)=>(x+y);
struct S
{
static auto foo(immutable int x)
{
return (immutable int y)=>(x+y);
}
}
class C
{
static auto foo(immutable int x)
{
return (immutable int y)=>(x+y);
}
}
void main()
{
writefln("global\t%s",foo(1)(2));
writefln("struct\t%s",S.foo(1)(2));
writefln("class\t%s",C.foo(1)(2));
}
それはうまく動作します:
global 3
struct 3
class 3
また、デリゲートを使用する利点もあります (コンパイラは最初のバージョンではデリゲートを許可しません)。ただし、このスタイルはあまりエレガントではありません。
curry
Dのライブラリに関数をカリー化するための関数があることはよく知っていますが、std.functional
関数をデフォルトでカリー化可能にする方が快適な場合もあります。また、最初のバージョンが機能しない理由を知りたいと思っています。
何か案は?
アップデート
OK、バグを報告しました。foo
さらに掘り下げてみたところ、 gets の引数リストがシフトされていることが判明しましたx
。