2

私は、オブジェクト指向のメソッドを使用してこの問題を正しく解決する方法を考えようとしています。言語は重要ではありません。実際にコードを書きたいのですが、それは私が気にかけているより一般的な原則です。

フィールドを実装したい:操作+、-、*、および/が操作される「数値」のコレクション。さらに、^や循環検出などのより高度な操作を実装できるようにしたいと思います。これらの操作は、(1)特定のフィールドに対して定義する必要はありませんが、(2)効率上の理由から、必要に応じてオーバーライドできます。

これがキャッチです。宣言するのは十分ではありません

FieldElement power (FieldElement base, FieldElement exponent)

型安全性が必要なためです。たとえば、有限体のメンバーを整数に追加することはできません。

おそらく、私が本当に探しているのは、メタオブジェクト、スーパーインターフェイス、または異なるクラス(1つは整数用、1つは7アディック用、1つは有限体F_4用など)を結び付けるものです。あるいは、もっと良いものがあるかもしれません。

NBコードは、それが啓発的であるならば、答えで歓迎されます(奨励されさえします)が、宣言はおそらく十分です:おそらくここの誰もが少なくともいくつかのフィールドのための明白なメソッドを書き出すことができます。


私にとって重要であるが、(明らかに)OOの主要な問題とは関係のない他の条件について説明します。フィールド要素に型情報を伝達させたくないし、さらに軽量にしたい(必要になるかもしれないので)フィールド要素の大きな配列を処理します)。これらのdesiderataは達成できない可能性がありますが、率直に言って、効率よりもここでOOを放棄する可能性が高くなります。しかし、私は目前の特定の問題とは別にこれらの問題について学ぶことに興味があるので、答えは関係なくありがたいです。

4

2 に答える 2

2

これはバイナリメソッド問題と呼ばれます。すばやくグーグルすると、いくつかの(たくさんの)情報が明らかになります。特に、Luca Cardelliらによる「バイナリメソッドについて」の記事は、対象に徹底的な治療を提供します。

Haskellを学び、実用的なプログラミング言語がこの問題をどのように処理するかを確認することをお勧めします。

Loluca→Lucaを編集します。小さな電話スクリーンとその小さなキーボードを酷評しなさい;)

于 2012-05-17T02:17:00.727 に答える
1

私は以前にこれらの概念をC#で表現しようとしましたが、言語の壁に遭遇しました。言語は十分に豊富ではないか、十分に具体的ではありません。たとえば、次のようにフィールドの要素を定義すると、次のようになります。

public abstract class FieldElement 
{
    public abstract FieldElement Add(FieldElement another);
    public abstract FieldElement SumInvert();
    public abstract FieldElement MultiplicationInvert();
    public abstract FieldElement MultiplyBy(FieldElement another);
    public abstract FieldElement One; //Multiplication neutral element
    public abstract FieldElement Zero; //Addition neutral element

    public FieldElement Subtract(FieldElement another)
    {
        return this.Add(another.SumInvert());
    }

    public FieldElement Divide(FieldElement another)
    {
        return this.MultiplyBy(another.MultiplicationInvert());
    }
    public virtual FieldElement Power(uint b)
    {
        if (b == 0)
            return this.One;
        else
        {
            FieldElement result = this;
            for (int i = 0; i < b - 1; i++)
                result = result.MultiplyBy(result);
            return result;
        }
    }
}

次に、次のように実数を定義します。

public class RealNumber : FieldElement
{
    public double Value { get; set; }

    public RealNumber(double value)
    {
        this.Value = value;
    }
    public override FieldElement Power(uint b)
    {
        return new RealNumber(Math.Pow(Value, b));
    }
    public override FieldElement Add(FieldElement another)
    {
        if (another.GetType() != typeof(RealNumber)) //Ugly typecast to enforce type-safety
            throw new ArgumentException("RealNumber expected in Add method");

        return new RealNumber(Value + (another as RealNumber).Value);
    }
}

次に、フィールド要素に対するジェネリック操作を(ジェネリックを使用して)定義できます。

public class FieldOperations<T> where T: FieldElement 
{
    public T Add(T a, T b)        
    {
        return a.Add(b) as T;
    }
    public T Multiply(T a, T b)
    {
        return a.MultiplyBy(b) as T;
    }
    public T Subtract(T a, T b)
    {
        return a.Subtract(b) as T;
    }
    public T Divide(T a, T b)
    {
        return a.Divide(b) as T;
    }
    public T Power(T a, uint b)
    {
        return a.Power(b) as T;
    }   
}

そして、私はそれをコードで次のように使用します:

public class TestFieldOperations
{
    public static void TestAddRealNumbers()
    {
        FieldOperations<RealNumber> operations = new FieldOperations<RealNumber>();
        RealNumber a = new RealNumber(0.5);
        RealNumber b = new RealNumber(0.7);
        RealNumber c = operations.Add(a, b);
        RealNumber d = operations.Power(c, 3);
    }
}

同様に、VectorsでFieldOperations、InvMatrixでFieldOperationsを使用できます...

タイプセーフでオブジェクト指向の方法でフィールド操作の概念を抽象化できることは、非常に強力です。同じレベルの抽象化で、数値、ベクトル、および(可逆)行列演算を処理できることです。

于 2012-05-17T02:43:06.507 に答える