1

我想要一个换行符分隔的表示,而不是通常的逗号分隔的表示,因为可能有新的数据类型:

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

我试图写这个 istance 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 严重侮辱我。

有人可以尝试向我解释我该怎么办吗?

4

3 回答 3

4

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

话虽如此,几乎每个人都将它误用于后者,它有助于调试目的。

因此,您的选择是:

  1. 编写一些未调用show的函数来执行您想要的操作。(根据AndrewC的评论。)

  2. 使用showList方法。

如果你写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
于 2012-09-12T11:12:28.983 回答
1

你的问题很模棱两可。如果我解释正确,您正在尝试Show更改[SimpleRecord].

由于 GHC 已经定义了实例Show [a] whenShow 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 

在部分构造函数应用程序等方面,您在这里获得了更大的灵活性。

于 2012-09-11T22:06:57.090 回答
1

我可能遗漏了一些东西,但不清楚您为什么要输入新类型 (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)
于 2012-09-12T02:40:51.047 回答