Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 类型类之间的关系-依赖关系与使用实例_Haskell_Typeclass - Fatal编程技术网

Haskell 类型类之间的关系-依赖关系与使用实例

Haskell 类型类之间的关系-依赖关系与使用实例,haskell,typeclass,Haskell,Typeclass,假设我想为半群和幺半群定义自己的类型类。所以我写了这段代码: class Semigroup g where (<>) :: g -> g -> g class Semigroup m => Monoid m where mempty :: m 后一种设计有一个优点——以后我可以为Monoid添加更多实例。例如,如果我有一个向量空间的typeclass,我可以稍后将其设置为加法组,而不必在类声明中指定它。另一方面,我被迫使用灵活的实例和不可判定的

假设我想为半群和幺半群定义自己的类型类。所以我写了这段代码:

class Semigroup g where
    (<>) :: g -> g -> g

class Semigroup m => Monoid m where
    mempty :: m
后一种设计有一个优点——以后我可以为Monoid添加更多实例。例如,如果我有一个向量空间的typeclass,我可以稍后将其设置为加法组,而不必在类声明中指定它。另一方面,我被迫使用灵活的实例和不可判定的实例

我的问题是-对于这种特殊情况,什么是最佳设计?

第一个版本说“幺半群是半群,具有附加属性
mempty

第二个肯定词说“所有类型都是半群,只要它们也是幺半群”。除非您乐于打开重叠实例,否则无法添加任何其他实例,因此这相当于“类型是半群,当且仅当它是幺半群”;与真正的关系完全背道而驰


我几乎总是喜欢前者。是的,它迫使想要添加
幺半群
实例的人也编写
半群
实例,但他们必须做的真正“工作”是相同的:决定
mempty
mappend
的实现。通过使用第二种方法,您唯一可以避免它们的是一个小样本。

这里的“更好”是一个非常困难的术语——我的问题是:为什么要重新定义它?话虽如此:我更喜欢第一个(不可判定的符号在我看来是一个危险信号),我想写我自己的线性代数库,想有一些舒适的类,比如向量空间和环。幺半群和半群只是作为一个例子。是的,我想是公平的-但这确实不是最好的问题(你可能会得到一些密切的标志,因为它似乎有点基于表面的意见)-也许更好的主意是去做reddit或haskell IRC频道/邮件列表来讨论这个(?)-尤其是在以后的日子里,你会有很多非常聪明的人,他们会很快告诉你为什么一个或另一个是你要走的路;)我真的不知道有什么好处。你能否澄清一下,在允许不可判定的实例的代价下,你用第二个代码相对于第一个代码赚了多少钱?在我看来,灵活和不可判定的实例在实践中是无害的。然而,如果你想要一些不是幺半群的半群,那么第二种方法需要重叠的实例,而这正是真正的痛苦所在。重叠和不连贯的实例具有相当微妙的语义,很难理解,并且很容易导致不必要的意外。
class Semigroup g where
    gappend :: g -> g -> g

class Monoid m where
    mempty :: m
    mappend :: m -> m -> m

instance Monoid m => Semigroup m where
    gappend = mappend