将包含所有操作的自定义haskell类型封装到一个类中

时间:2015-03-26 02:47:45

标签: c++ haskell custom-data-type

如果我想在C ++中创建一个新类型,我会在其中重载一堆运算符,我可以这样做:

class Stringy {
    public:
    explict Stringy(const char *buffer){}
    friend Stringy operator + (const Stringy &s1, const Stringy &s2) { ... }
    friend Stringy operator - (const Stringy &s1, const Stringy &s2) { ... }
    friend std::ostream& operator << (std::ostream &oss, const String& s1) { ... }
};

现在如果我试图在Haskell中做同样的事情,我发现自己在做(一个例子):

data Stringy = Stringy([Char])
-- do something unrelated here --
(+) :: Stringy -> Stringy -> Stringy
(-) :: Stringy -> Stringy -> Stringy
(removeDups) :: Stringy -> Stringy
-- do something else unrelated here --
(>>) :: Stringy -> IO --(is IO right?)

我的观点是c ++看起来更加放在一起,因为你在该类中所做的一切都以某种方式与类相关。另一方面,haskell one的操作员声明可能遍布整个地方而不需要在一起。如果有人看一下c ++代码,他们可以立即识别哪些操作是类的一部分而哪些不是。我如何在Haskell中实现同样的一致性?

我仍然是Haskell的初学者,所以请使用简单的做事方式。感谢

1 个答案:

答案 0 :(得分:1)

正如丹尼尔所说,优秀的图书馆设计师确实试图将相关功能放入同一个模块中。通常情况下,类型Stringy以及Stringy上的所有“基本”操作都位于模块Stringy(或X.Y.Z.Stringy)中,文件{{1 }}

最终,我认为您会欣赏Haskell为您提供的灵活性。 例如,假设您要定义类型为

的函数
Stringy.hs

这不适用于三个类型类中的任何一个(myfunction :: Stringy -> Thingy -> Doohicky StringyThingy),因为它引用的类型不属于类型类。 也许这三个类型分为三个单独的模块,很久以前由不同的人编写。 你是第一个意识到Doohicky将是一个有用的操作的人。 Haskell允许您将此功能放在您认为最有意义的地方。 您可以创建一个全新的模块,专门用于从其他类型类的值组合生成myFunction的方法。