[英]Making a data type an instance of Show in Haskell
我需要使以下數據類型成為Show
一個實例:
data Tree a b = Branch b (Tree a b) (Tree a b) | Leaf a
我對此很新,但首先,我將此聲明解釋為
“我們創建了一個名為Tree的新類型,它使用類型a和b進行參數化。樹可以是兩個東西之一:一個分支,它包含一個b類型的數據,另外兩個樹,或一個葉子,它持有類型為a的數據項。“
現在,我需要做一個很好地“展示”它的方法(嵌套分支等),而不使用deriving
。 到目前為止,我只是在一個模塊Main中編寫函數,並在解釋器窗口中加載/播放它們,所以我之前並沒有實際使用構造函數等。 不過,我想我可以從我的文件中聲明樹數據類型開始,如問題開頭所示,然后從那里開始。
當我用“Show”搞砸了沒有太大的成功時,我想也許我需要在嘗試使用整個樹之前定義樹的一個小組件以及如何首先“顯示”它:
data Leaf a = Leaf a
instance Show (Leaf a) where
show (Leaf a) = ???
我在???中嘗試了很多東西? 現貨,比如“a”,只是一個單獨的,putStrLn等,但當我說出類似的東西時,沒有一個打印出來的值a
>show (Leaf 3)
事實上,我在很多情況下遇到過這種情況,這可能意味着我找不到合適的東西:
Ambiguous occurrence `show'
It could refer to either `Main.show', defined at a2.hs:125:1
or `Prelude.show',
imported from `Prelude' at a2.hs:2:8-11
(and originally defined in `GHC.Show')
...我通過調用“Main.show”來解決這個問題,當然這不起作用。
我想問題是,我在哪里可以使用所有這些...或者只是,“我如何修復Leaf”Show“實用程序,以便我可以弄清楚如何擴展它?” (假設我必須先定義它......)
你必須這樣開始:
data Tree a b = Branch b (Tree a b) (Tree a b) | Leaf a
instance (Show a, Show b) => Show (Tree a b) where
show (Leaf x) = show x
show (Branch p l r) = ???
為了show
一個Tree ab
,你必須首先能夠show
a
S和b
秒。 這就是(Show a, Show b) =>
part所做的,它指定了實例工作所需的前提條件。
這是一個小小的暗示:通過寫作
instance Show (Leaf a) where
show (Leaf a) = ???
你實際做的是定義一個空的 Show
實例,然后是一個頂級的show
函數。 這就是你得到“模糊show
”錯誤的原因; 你已經定義了一個新的show
函數,它的名字與現有的函數相沖突。
你的意思是
instance Show (Leaf a) where
show (Leaf a) = ???
注意第二行現在是如何縮進的。 這意味着您正在重新定義現有的show
方法,正如您可能想要的那樣。
最簡單的答案是自動派生一個Show
實例:
data Tree a b = Branch b (Tree a b) (Tree a b) | Leaf a deriving Show
但是,讓我們說這並不能為您提供所需形式的輸出。 如果要定義自己的Show
實例,可以執行以下操作:
instance (Show a, Show b) => Show (Tree a b) where
show (Leaf a) = "Leaf " ++ (show a)
show (Branch b l r) = "Branch " ++ (show b) ++ " { " ++ l ++ ", " ++ r " }"
您可能會讀到第一行的方式是“給定a
和b
都是Show
類型類的實例, Tree ab
也是Show
類型類的實例......”
順便說一句, 縮進很重要 。 它可能在您粘貼的代碼段中被破壞,但您必須在instance
聲明下縮進show
函數定義。
您的數據類型是deriving Show
的完美候選者。
data Tree a b = Branch b (Tree a b) (Tree a b) | Leaf a deriving Show
這將自動為您生成Show實例。
如果你想創建一個Show的手動實例,這里是思考過程。
一,基本骨架:
instance Show (Tree a b) where
-- show :: Tree a b -> String
show (Branch b ltree rtree) = {- some string -}
show (Leaf a) = {- some string -}
現在我們知道我們需要一些方法來將a
和b
類型a
值顯示為字符串。 當然,這意味着我們需要能夠直接調用show
,所以a
和b
必須有Show的實例。 這是如何完成的:
instance (Show a, Show b) => Show (Tree a b) where
-- show :: Tree a b -> String
show (Branch b ltree rtree) = {- some string -}
show (Leaf a) = {- some string -}
然后它只是用適當的字符串填充空白,例如:
instance (Show a, Show b) => Show (Tree a b) where
-- show :: Tree a b -> String
show (Branch b ltree rtree) = "(( " ++ show ltree ++ " ) <-- ( " ++ b ++ " ) --> ( " ++ show rtree ++ " ))"
show (Leaf a) = "L " ++ show a
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.