Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.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
Class 如何定义超类?_Class_Haskell_Instance - Fatal编程技术网

Class 如何定义超类?

Class 如何定义超类?,class,haskell,instance,Class,Haskell,Instance,如何在Haskell中定义一个超类?我的情况是,我已经定义了一个类StringHashed,它将成员映射到他们的名称作为字符串。我希望通过让字符串名简单地返回showt来实现t中的所有t。我说的stringhash现在是Show的超类,对吗?以下是我希望能够写的: class StringHashed t where stringHash :: t -> String instance Show t => StringHashed t where stringHas

如何在Haskell中定义一个超类?我的情况是,我已经定义了一个类
StringHashed
,它将成员映射到他们的名称作为字符串。我希望通过让字符串名简单地返回
showt
来实现
t
中的所有
t
。我说的
stringhash
现在是Show的超类,对吗?以下是我希望能够写的:

class StringHashed t where
    stringHash :: t -> String

instance Show t => StringHashed t where
    stringHash = show

但是Haskell抱怨实例声明无效。我还尝试了
实例stringhash(showt)
和其他语法运球;没有人为我工作过。我还阅读了GHC wiki上的一份提案,该提案没有提供任何解决方案。我之所以担心使用
-XFlexibleInstances
,仅仅是因为它不是默认值。是否有适当的方法来实现通用实例声明?还是我对Haskell的类型系统要求太高了?

Haskell超类不能在事实之后添加-它们需要在子类的声明中提到。像您在问题中所做的那样定义一个实例,虽然可以使用扩展,但会产生微妙的重叠问题

FlexibleInstances
本身不是问题——它是GHC最无害的扩展之一。问题是GHC的实例查找方法意味着

instance Show t => StringHashed t where ...
定义此实例以适用于所有类型
t
-
Show t
限制仅在查找后进行事后检查。因此,它将与您可以创建的所有其他实例重叠,虽然有一个扩展
OverlappingInstances
,允许这样做,但使用它有点可疑

但是,GHC有一个功能
DefaultSignatures
,它是为与您类似的用例而设计的:

{-# LANGUAGE DefaultSignatures #-}

class StringHashed t where
    stringHash :: t -> String
    default stringHash :: Show t => t -> String
    stringHash = show

instance StringHashed Int

这允许您为只适用于某些实例类型的方法编写默认值。但是请注意,您仍然需要为每个类型编写一个实际的实例声明,但是它的主体可以为空。

对于超类使用
class(Show t)=>StringHashed t,其中
。但是我不确定这个实例是否真的是您想要的。对于非
Show
s的实现呢?我想我只能用这种方式构建子类。是的,我觉得这似乎有点希望。谢谢你的回答和解决办法。我想我会坚持哈斯凯尔的原则——那样我就不会惹麻烦了。@bimmo你应该尝试你认为合理的东西,有些可能会奏效。您最初的实例声明没有根本性的错误,只是Haskell目前的工作方式不同。