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
}

现在,我查看了 haskell 中可能用作 std::vector 的各种容器:有列表、未装箱的向量、装箱的向量,以及一些奇怪的外来指针用法,如下所示:

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++ 代码。

(编辑:stackoverflow 政策是否允许通过编辑(不是次要的)审查问题?它确实说“始终尊重原作者。”)

4

1 回答 1

3

如果你在 Haskell 中编写整个程序,除非你有充分的理由不这样做,否则只使用一个列表。(如果您确实有充分的理由不这样做,请说出它是什么,我们可以帮助您选择更合适的数据结构。例如,对特定列表元素的随机访问是 O(n) 而不是 O(1) C++ 向量和更新数据结构中的值在 Haskell 中是不同的。)

如果您在同一个程序中混合使用 Haskell 和 C++,并且需要帮助从 Haskell 调用 C++,请说。

  • 默认使用列表。编译器可以将诸如 和 之类的列表操作map融合在一起,从而产生比使用 ​​C++ 向量通常获得的更高效的代码。foldrfilter
  • 如果您发现自己需要按索引查找元素,或者想要在特定索引处改变元素,请使用某种数组。请参阅Data.ArrayData.Array.IOData.Array.ST
  • 如果您发现自己需要在数据结构的中间或结构的两端插入新元素,请使用序列。请参阅数据.序列
于 2012-04-14T16:50:46.180 回答