bim*_*mmo 4 haskell class instance
如何在Haskell中定义超类?我的情况是我已经定义了一个类StringHashed,它将成员的名称映射为String.我希望实现,连接质量,所有t从Show t通过将字符串名称简单地返回show t.我是否正确地说StringHashed现在是Show的超类?以下是我想写的内容:
class StringHashed t where
stringHash :: t -> String
instance Show t => StringHashed t where
stringHash = show
Run Code Online (Sandbox Code Playgroud)
但是Haskell抱怨无效的实例声明.我也尝试过instance StringHashed (Show t)其他语法运球; 没有人对我有用.我还阅读了关于GHC wiki的提议,但没有提供任何解决方案.这是一个.我担心使用-XFlexibleInstances只是因为它不是默认的.有没有一种正确的方法来实现一般的实例声明?或者我对Haskell的类型系统要求太高了?
Ørj*_*sen 10
事后不能添加Haskell超类 - 需要在子类的声明中提及它们.定义像你在问题中所做的实例,虽然可能有扩展,但可能会产生细微的重叠问题.
FlexibleInstances本身不是问题 - 它是GHC最无害的扩展之一.问题是GHC的实例查找方法意味着
instance Show t => StringHashed t where ...
Run Code Online (Sandbox Code Playgroud)
将此实例定义为适用于所有类型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
Run Code Online (Sandbox Code Playgroud)
这允许您为仅适用于某些实例类型的方法编写默认值.但请注意,您仍需要为每种类型编写实际的实例声明 - 但它的主体可以为空.