Class 如何定义超类?
如何在Haskell中定义一个超类?我的情况是,我已经定义了一个类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
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目前的工作方式不同。