2012-09-11 26 views
1

我想換行分隔的表現,而不是通常用逗號分隔的一個,5月份新數據tyepe:超載秀列表

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嚴重侮辱我。

有人可以試着解釋我該怎麼辦?

+3

類'Show'有一個方法'showList'這樣你就可以定製的。這就是字符串又名「[Char]」的不同之處。注意 - 你不能爲SimpleRecord派生'Show',你必須自己做,並且同時定義'showList'。 –

+1

你可以編寫一個不叫'show'的函數並使用它。 – AndrewC

回答

2

首先,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) 

順便說一句,如果你還不知道這一點,你可以在GHCI寫

mapM_ print records 

提示打印出任意可打印的東西列表,每行一個元素。


作爲最後asside,爲什麼

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

而不是

data SimpleRecord = SimpleRecord [Char] [Char] Integer 
+0

否(再次) - 'Show'不應該用於_producing Haskell output_。它用於將Haskell值轉換爲字符串。請閱讀Haskell報告中的相關章節。當然,如果Show和Read實例之間存在對應關係,則有一些優點,但沒有義務。 –

+0

@stephentetley關於派生'Show'實例的部分:「Show的結果是一個語法正確的Haskell表達式......」。雖然自定義的'Show'實例沒有這種行爲的義務,它*有意爲默認設置。 http://www.haskell.org/onlinereport/haskell2010/haskellch11.html#x18-18600011.4 –

1

你的問題很模糊。如果我的解釋正確,您正嘗試更改的默認Show實例。

由於當定義了Show a時,GHC已經定義了實例Show [a]。當您嘗試再次爲Show [SimpleRecord]定義實例時,出現以下錯誤(包括FlexibleInstances擴展名)。

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 

你得到mo在部分構造應用程序等方面的靈活性。

+2

這對大多數課程都是如此。但是'Show'包含了這種情況的一個可怕的黑客攻擊。您可以爲您的類型提供不同的'showList'實現來自定義類型列表的處理方式。 – Carl

+0

值得指出的是show實例有一個不具有描述性的模式匹配嗎? – Phyx

1

我可能錯過了一些東西,但不清楚爲什麼你是newtyping(字符串,字符串,整數)而不是你所關心的很好顯示,即他們的名單。然後,你會逃避普遍顯示實例列表:

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)