1

私はhaskellを初めて使用するので、haskellで次のC++コードを再作成しようとしています。

int main() {
    class MyClass {
        public:
        int a;
        std::string s;
        float f;
    };
    std::vector <MyClass> v;
    LoadSerialized(&v); // don't need haskell equivalent; just reads a bunch of MyClass's and pushes them back onto v
}

ここで、std :: vectorとして機能する可能性のあるhaskellのさまざまなコンテナーを確認しました。リスト、ボックス化されていないベクトル、ボックス化されたベクトル、および次のような外部ポインターの奇妙な使用法があります。

data Table = Table { floats :: ForeignPtr CFloat
                   , ints   :: ForeignPtr Int    }

newTable :: IO Table
newTable = do
    fp <- S.mallocByteString (floatSize * sizeOf (undefined :: CFloat))
    ip <- S.mallocByteString (intSize   * sizeOf (undefined :: Int   ))
    withForeignPtr fp $ \p ->
        forM_ [0..floatSize-1] $ \n ->
            pokeElemOff p n pi
    withForeignPtr ip $ \p ->
        forM_ [0..intSize-1]   $ \n ->
            pokeElemOff p n n
    return (Table fp ip)

これで、C ++コードを、私が最善だと思う方法で実装できました。つまり、Haskellの初心者です。または、言語に詳しい人に、最善の方法を尋ねることもできます。私には、ここで欠けているニュアンスがあるように見えるからです。簡単に言うと、多くのデータ型を含む構造体をhaskellコンテナーにプッシュしたいので、順序は気にしません。それが役に立ったら、でわかるように、シリアル化されたデータをコンテナに読み込みますLoadSerialized

私はC++コードを混ぜていません。

(編集:編集による質問の検閲を許可するのはスタックオーバーフローポリシーですか(マイナーではありません)?「常に元の作成者を尊重する」と書かれています。)

4

1 に答える 1

3

Haskell でプログラム全体を書いている場合は、正当な理由がない限りリストを使用してください。(そうしない正当な理由がある場合は、それが何であるかをお知らせください。より適切なデータ構造を選択するお手伝いをいたします。たとえば、特定のリスト要素へのランダム アクセスは、a の O(1) ではなく O(n) です。 Haskell では、データ構造の値の更新は C++ ベクトルとは異なります。)

Haskell と C++ を同じプログラムに混在させていて、Haskell から C++ を呼び出すのに助けが必要な場合は、言ってください。

  • デフォルトでリストを使用します。map、 、foldrなどのリスト操作をfilterコンパイラで融合できるため、C++ ベクトルを使用して通常取得するよりも効率的なコードが得られます。
  • インデックスで要素を検索する必要がある場合、または特定のインデックスで要素を変更したい場合は、何らかの配列を使用してください。Data.ArrayData.Array.IO、およびData.Array.STを参照してください。
  • データ構造の途中または構造の両端に新しい要素を挿入する必要がある場合は、シーケンスを使用します。Data.Sequenceを参照してください。
于 2012-04-14T16:50:46.180 に答える