访问“默认显示”在Haskell中? [英] Accessing the "default show" in Haskell?

查看:110
本文介绍了访问“默认显示”在Haskell中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您有一个数据结构(借用此问题):

 数据希腊语= Alpha | Beta |伽玛| Delta | Eta |数字Int 

现在可以使它成为 Show 通过在该指令中附加派生Show



然而,我们希望显示 Number Int as:

  instance显示希腊语
show(Number x)=显示x
- ...

问题是必须指定 希腊数据的所有其他部分也如下所示:

  show Alpha =Alpha
show Beta =Beta

这当然是可行的。但是,如果选项数量很长,则需要大量工作。

我想知道是否可以访问默认显示实现并调用它带有通配符。例如:

  instance显示希腊语
show(Number x)= show x
show x = defaultShow x

因此,您可以实施与默认方法不同的特定模式,

有些类似于方法覆盖引用 super.method 在面向对象的编程中。

解决方案

您可以使用Data和Typeable来完成此任务。这当然是一种破解,而且这个例子只适用于你的例子中的枚举类型。



我确信我们可以更详细地了解我们如何做到这一点,但要涵盖您给出的示例:

  { - #LANGUAGE DeriveDataTypeable# - } 
import Data.Data
import Data.Typeable

data Greek = Alpha | Beta |伽玛| Delta | Eta | Number Int
derived(Data,Typeable)

instance显示希腊语
显示数字n显示n
显示x =显示$ toConstr x

这种方法我实现它不能处理嵌套的数据结构或其他任何远程花哨的东西,但这又是一个丑陋的黑客攻击。如果你真的必须使用这种方法,你可以在 Data.Data 包中进行挖掘,我相信你可以把东西拼凑在一起......



下面是一篇博客文章,快速介绍这些软件包: http://chrisdone.com/posts/data-typeable



正确的方法是使用 newtype wrapper。我意识到这不是最方便的解决方案,尤其是在使用GHCi时,但它不会带来额外的开销,并且随着程序的增长不太可能以意想不到的方式突破。

 数据希腊语= Alpha | Beta |伽玛| Delta | Eta |数字Int 
导出(显示)

newtype SpecialPrint = SpecialPrint希腊

实例Show SpecialPrint其中
show(SpecialPrint(Number x))=Number :++ show x
show(SpecialPrint x)= show x

main = do
print(SpecialPrint Alpha)
print(SpecialPrint $ Number 1)


Say you have a data-structure (borrowed from this question):

data Greek = Alpha | Beta | Gamma | Delta | Eta | Number Int

Now one can make it an instance of Show by appending deriving Show on that instruction.

Say however we wish to show Number Int as:

instance Show Greek where
    show (Number x) = show x
    -- ...

The problem is that one must specify all other parts of the Greek data as well like:

    show Alpha = "Alpha"
    show Beta = "Beta"

For this small example that's of course doable. But if the number of options is long, it requires a large amount of work.

I'm wondering whether it is possible to access the "default show" implementation and call it with a wildcard. For instance:

instance Show Greek where
    show (Number x) = show x
    show x = defaultShow x

You thus "implement" the specific patterns that differ from the default approach and the remaining patterns are resolved by the "fallback mechanism".

Something a bit similar to method overriding with a reference to super.method in object oriented programming.

解决方案

You can sorta accomplish this using Data and Typeable. It is a hack of course, and this example only works for "enumerated" types as in your example.

I'm sure we could get more elaborate with how we do this, but to cover your given example:

{-# 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

This approach as I've implemented it cannot handle nested data structures or anything else remotely fancy, but again, this is an ugly hack. If you really must use this approach you can dig around in the Data.Data package I'm sure you could piece something together...

Here is a blog post giving a quick introduction to the packages: http://chrisdone.com/posts/data-typeable

The proper way to go about this would be to use a newtype wrapper. I realize that this isn't the most convenient solution though, especially when using GHCi, but it incurs no additional overhead, and is less likely to break in unexpected ways as your program grows.

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)

这篇关于访问“默认显示”在Haskell中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆