6

私は 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

ご覧のとおり、私の方法はグローバル関数変数に対してはうまく機能しますが、構造体の静的関数変数はジャンクな結果を出し、クラスの静的関数変数は完全に失敗します。xreturn 式からを削除すると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

また、デリゲートを使用する利点もあります (コンパイラは最初のバージョンではデリゲートを許可しません)。ただし、このスタイルはあまりエレガントではありません。

curryDのライブラリに関数をカリー化するための関数があることはよく知っていますが、std.functional関数をデフォルトでカリー化可能にする方が快適な場合もあります。また、最初のバージョンが機能しない理由を知りたいと思っています。

何か案は?

アップデート

OK、バグを報告しましたfooさらに掘り下げてみたところ、 gets の引数リストがシフトされていることが判明しましたx

4

1 に答える 1

4

正直なところ、コンパイラのバグに遭遇したようです。報告してください。構造体とクラスの変数は静的であるため、それらの動作はモジュール レベルの変数の動作と同じである必要がありますが、明らかにそうではありません。

于 2012-06-11T18:24:04.993 に答える