Wil*_*sem 7 haskell overriding typeclass
假设你有一个数据结构(借用这个问题):
data Greek = Alpha | Beta | Gamma | Delta | Eta | Number Int
Run Code Online (Sandbox Code Playgroud)
现在可以Show通过附加deriving Show该指令使其成为一个实例.
然而,我们希望表现Number Int为:
instance Show Greek where
show (Number x) = show x
-- ...
Run Code Online (Sandbox Code Playgroud)
问题是必须指定Greek数据的所有其他部分,如:
show Alpha = "Alpha"
show Beta = "Beta"
Run Code Online (Sandbox Code Playgroud)
对于这个小例子,当然可行.但是如果选项的数量很长,则需要大量的工作.
我想知道是否可以访问"默认show"实现并使用通配符调用它.例如:
instance Show Greek where
show (Number x) = show x
show x = defaultShow x
Run Code Online (Sandbox Code Playgroud)
因此,您"实现"与默认方法不同的特定模式,其余模式由"回退机制"解决.
与super.method面向对象编程中的引用重叠的方法有点类似.
小智 7
不,那是不可能的AFAIK.
此外,自定义的情况下,Show应该有一个第二个想法,因为Show和Read实例应相互兼容.
对于只转换为人类(或任何人)可读字符串,请使用您自己的函数或自己的类型类.这也将实现你想要的:
假设您有一个Presentable带有方法的类型类present,以及默认Show实例,您可以编写:
instance Presentable Greek where
present (Number x) = show x
present x = show x
Run Code Online (Sandbox Code Playgroud)
您可以使用Data和Typeable来完成此操作.当然这是一个hack,这个例子只适用于你的例子中的"枚举"类型.
我相信我们可以更详细地了解我们如何做到这一点,但是要涵盖你给出的例子:
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Data
import Data.Typeable
data Greek = Alpha | Beta | Gamma | Delta | Eta | Number Int
deriving (Data,Typeable)
instance Show Greek where
show Number n = show n
show x = show $ toConstr x
Run Code Online (Sandbox Code Playgroud)
我实现它的这种方法无法处理嵌套数据结构或任何其他远程花哨的东西,但同样,这是一个丑陋的黑客.如果你真的必须使用这种方法,你可以在Data.Data包中挖掘我相信你可以拼凑一些东西......
这是一篇博客文章,简要介绍了这些软件包:http://chrisdone.com/posts/data-typeable
解决这个问题的正确方法是使用newtype包装器.我意识到这不是最方便的解决方案,特别是在使用GHCi时,它不会产生额外的开销,并且随着程序的增长不太可能以意想不到的方式中断.
data Greek = Alpha | Beta | Gamma | Delta | Eta | Number Int
deriving (Show)
newtype SpecialPrint = SpecialPrint Greek
instance Show SpecialPrint where
show (SpecialPrint (Number x)) = "Number: " ++ show x
show (SpecialPrint x) = show x
main = do
print (SpecialPrint Alpha)
print (SpecialPrint $ Number 1)
Run Code Online (Sandbox Code Playgroud)
正如@phg在评论中指出的那样,这也可以通过泛型派生来完成:
{-# LANGUAGE DeriveGeneric #-}
module Main where
import Generics.Deriving.Base (Generic)
import Generics.Deriving.Show (GShow, gshow)
data Greek = Alpha | Beta | Gamma | Delta | Eta | Number Int
deriving (Generic)
instance GShow Greek
instance Show Greek where
show (Number n) = "n:" ++ show n
show l = gshow l
main :: IO ()
main = do
print (Number 8)
print Alpha
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1364 次 |
| 最近记录: |