超载显示列表

时间:2012-09-11 21:55:44

标签: haskell newtype

我想要一个以换行符分隔的表示形式,而不是通常用逗号分隔的表示形式,因为可能是新数据tyepe:

newtype SimpleRecord = SimpleRecord ([Char], [Char], Integer)
    deriving (Show)

我试着写下Show class

的这个等级
instance  Show [SimpleRecord] where
        show [(SimpleRecord (n, i, c))] = show (SimpleRecord (n, i, c))++['\n']
        show (l:ls) = (show l)++['\n']++(show ls)

GHC严重侮辱我。

有人可以试着解释一下我该怎么办?

3 个答案:

答案 0 :(得分:3)

首先,Show假设用于生成Haskell源代码,然后Read类可以读回来。它不应该是用于产生人类可读的“漂亮”输出。

刚才说过,几乎每个人都会误用它,这对调试来说很有帮助。

所以,你的选择是:

  1. 编写一些名为show的函数,它可以满足您的需求。 (根据AndrewC的评论。)

  2. 使用showList方法。

  3. 如果您编写deriving Show,这会告诉编译器为您编写所有Show方法。如果您想自己编写,则需要先取消deriving位。然后你可以编写你的实例,它看起来像

    instance Show SimpleRecord where
      show (SimpleRecord (x, y, z)) = ...
    
      showList rs = unlines (map show rs)
    

    顺便说一句,如果您还不知道,可以写

    mapM_ print records
    

    在GHCi提示下打印任何可打印事物列表,每行一个元素。


    作为最后的帮助,为什么

    newtype SimpleRecord = SimpleRecord ([Char], [Char], Integer)
    

    而不是

    data SimpleRecord = SimpleRecord [Char] [Char] Integer
    

答案 1 :(得分:1)

你的问题非常模糊。如果我正确解释您正在尝试更改Show的默认[SimpleRecord]实例。

当定义Show [a]时,GHC已经定义了实例Show a。当您尝试再次为FlexibleInstances定义实例时,会出现以下错误(包括Show [SimpleRecord]扩展名后)。

Matching instances:
      instance Show a => Show [a] -- Defined in `GHC.Show'
      instance Show [SimpleRecord] -- Defined at show.hs:5:11

因此,您需要使用OverlappingInstances语言扩展来允许重载它。 它声明GHC与最具体的实例相匹配。

您可能还希望包含FlexibleInstances扩展名,它允许在实例声明中提及任意嵌套类型。

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverlappingInstances #-}
newtype SimpleRecord = SimpleRecord ([Char], [Char], Integer)
    deriving (Show)

instance  Show [SimpleRecord] where
    show [SimpleRecord (n, i, c)] = show (SimpleRecord (n, i, c))++"\n"
    show (l:ls) = show l ++ "\n" ++ show ls

您可以在GHC Docs

获取有关这些语言扩展的更多信息

只需对您的类型设计发表评论,最好将您的类型定义为

data SimpleRecord = SimpleRecord String String Integer 

在部分构造函数应用程序等方面,您可以获得更多灵活性。

答案 2 :(得分:1)

我可能已经遗漏了一些东西,但不清楚你为什么要newtyping(String,String,Integer)而不是你所关心的很好地显示它们,即它们的列表。然后你会逃避列表的通用Show实例:

newtype SimpleRecords = SimpleRecords [(String, String, Integer)]

instance Show SimpleRecords where
  show (SimpleRecords []) = ""
  show (SimpleRecords ((n, i, c): xs)) = 
       show (n, i, c) ++ "\n" ++ show (SimpleRecords xs)

 -- Prelude Main> let a = words "We hold these truths to be self-evident"
 -- Prelude Main> let b = words "All the best people are using Clorox"
 -- Prelude Main> let c = zip3 a b [1::Integer ..]
 -- Prelude Main> SimpleRecords c
 -- ("We","All",1)
 -- ("hold","the",2)
 -- ("these","best",3)
 -- ("truths","people",4)
 -- ("to","are",5)
 -- ("be","using",6)
 -- ("self-evident","Clorox",7)