我应该使用哪个容器?

时间:2012-04-14 16:39:16

标签: haskell

我是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政策?它确实说“始终尊重原作者。”)

1 个答案:

答案 0 :(得分:3)

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

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

  • 默认情况下使用列表。 mapfoldrfilter之类的列表操作可以由编译器融合在一起,从而产生比使用C ++向量通常更高效的代码。
  • 如果您发现自己需要按索引查找元素,或者想要改变特定索引处的元素,请使用某种数组。请参阅Data.ArrayData.Array.IOData.Array.ST
  • 如果您发现需要在数据结构的中间或结构的两端插入新元素,请使用序列。见Data.Sequence